/* /js/src/func.js */

//使IE支持Object.assign
if (typeof Object.assign != 'function') {
  Object.assign = function(target) {
    'use strict';
    if (target == null) {
      throw new TypeError('Cannot convert undefined or null to object');
    }

    target = Object(target);
    for (var index = 1; index < arguments.length; index++) {
      var source = arguments[index];
      if (source != null) {
        for (var key in source) {
          if (Object.prototype.hasOwnProperty.call(source, key)) {
            target[key] = source[key];
          }
        }
      }
    }
    return target;
  };
}

//使IE支持Array.includes 方法，判断指定元素是否存在于数组中。该方法也适用于字符串
(function(types) {
    types.forEach(function(type) {
        if (!type.prototype.includes) {
            type.prototype.includes = function(search, start) {
                if (typeof start !== 'number') {
                    start = 0;
                }
 
                if (start + search.length > this.length) {
                    return false;
                } else {
                    return this.indexOf(search, start) !== -1;
                }
            };
        }
    });
})([String, Array]);

//为日期类增加格式化方法
Date.prototype.format = function (fmt) {
    var o = {
        'M+': this.getMonth() + 1,
        'd+': this.getDate(),
        'H+': this.getHours(),
        'm+': this.getMinutes(),
        's+': this.getSeconds(),
        'S+': this.getMilliseconds()
    };
    //因为date.getFullYear()出来的结果是number类型的,所以为了让结果变成字符串型，下面有两种方法：
    if (/(y+)/.test(fmt)) {
        //第一种：利用字符串连接符“+”给date.getFullYear()+''，加一个空字符串便可以将number类型转换成字符串。
        fmt = fmt.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length));
    }
    for (var k in o) {
        if (new RegExp('(' + k + ')').test(fmt)) {
            //第二种：使用String()类型进行强制数据类型转换String(date.getFullYear())，这种更容易理解。
            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (('00' + o[k]).substr(String(o[k]).length)));
        }
    }
    return fmt;
};

/**
 * 如果指定checkbox选中，则返回其值，否则返回空
 */
function getChexkBoxVal(node){
    if(node.length<1){
        return "";
    }
    if(node[0].checked){
        return node.val();
    }
    return "";
}

/**
 * 从url中获取参数值
 */
function getRequest(key,paramUrl){
  var paraMap = getLocationParameterMap(paramUrl);
  var res = paraMap.get(key);
  if(!res){
    return "";
  }
  return decodeURI(res);
}

/**
 * 将URL中的参数转换成对照容器
 * paramUrl 动作路径
 */
function getLocationParameterMap(paramUrl){
  //获取调用路径
  if(!paramUrl){
      paramUrl = window.location.href;
    }
  //参数分割点
  var point = paramUrl.lastIndexOf("?");
  if(point>-1){
    //去掉动作路径
    paramUrl = paramUrl.substring(point+1,paramUrl.length);
    return paraStr2Map(paramUrl);
  }
  return new ValueMap();
}

/**
 * 参数字符串转换为参数容器
 */
function paraStr2Map(paraStr){
  //构建返回值
  var reMap = new ValueMap();
  var subPara; //参数段
    var point;   //参数分割点
  while(true){
    var fixOver = false; //是否处理结束
    point = paraStr.indexOf("&");
    if(point>-1){
      subPara = paraStr.substring(0,point);
      paraStr = paraStr.substring(point+1,paraStr.length);
    }else{
      subPara = paraStr;
      fixOver = true;
    }
    point = subPara.indexOf("=");
    if(point>-1){
      reMap.put(
        subPara.substring(0,point)
        ,subPara.substring(point+1,subPara.length));
    }
    if(fixOver){
      break;
    }
  }
  return reMap;
}

/**
 * 将容器转换为参数字符串
 */
function map2ParamStr(map){
  if(!map){
    return "";
  }
  var keyList = map.getKeyList();
  var key;
  var reStr = "";
  for(var i=0;i<keyList.size();i++){
    key = keyList.get(i);
    if(reStr!=""){
      reStr += "&";
    }
    reStr += key+"="+map.get(key);
  }
  return reStr;
}


/**
 * 提交XML内容
 * url 动作路径
 * xml 提交XML内容
 * 返回文本
 */
function postData(url,data){
  var xmlHttp;
  try{
    if(window.XMLHttpRequest){
      xmlHttp = new XMLHttpRequest();
    }else if(window.ActiveXObject){
      xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    if (url.indexOf("?")>-1){
        url+="&";
    }else{
        url+="?";
    }
    url+="_js=1&_ts_="+(new Date()).valueOf();

    if(data==null || data==""){
      xmlHttp.open("GET",url,false);
      xmlHttp.setRequestHeader("CONTENT-TYPE", "application/x-www-form-urlencoded");
      xmlHttp.send(null);
    }else{
      xmlHttp.open("POST",url,false);
      xmlHttp.setRequestHeader("CONTENT-TYPE", "application/x-www-form-urlencoded");
      xmlHttp.send(data);
    }
    return xmlHttp.responseText;
  }catch(ex){
    if(debug){
      alert("Error:\nAction:["+url+"]\nParams:["+data+"]\n"+ex);
    }
  }
}

/**
 * 提交Json字符串内容返回Json对象信息（注意：返回Json对象信息）
 * url   提交目标动作路径
 * json  json字符串
 */
function postJson(url,json){
  var method;
  if(json){
    method = "POST";
  }else{
    method = "GET";
  }
  if(!(typeof(json)=="string")){
    json = JSON.stringify(json);
  }
  if (url.indexOf("?")>-1){
      url+="&";
  }else{
      url+="?";
  }
  url+="_js=1&_ts_="+(new Date()).valueOf();
  var res = $.ajax({
      type: method,
      url:url,
      dataType:"json",
      beforeSend: function (xhr) {
        xhr.setRequestHeader("base64_enc", "1");
      },
      cache: false,
      async: false,
      type:"post",
      data:Base64.e64(json)
    }).responseText;
  if(res==""){
      return null;
  }
  var dataJson = null;
  try{
    eval("dataJson = "+res);
    if(dataJson.status==-99){
      return null;
    }
  }catch(e){}
  return dataJson;
}


/**
 * 提交XML内容返回Json信息（注意：返回Json格式信息）
 * url 提交目标动作路径
 * xml 提交内容
 */
function postXml(url,xml){
  var method;
  if(xml){
    method = "POST";
  }else{
    method = "GET";
  }
  if (url.indexOf("?")>-1){
      url+="&";
  }else{
      url+="?";
  }
  url+="_js=1&_ts_="+(new Date()).valueOf();
  var res = $.ajax({
      type: method,
      url:url,
      dataType:"xml",
      beforeSend: function (xhr) {
        xhr.setRequestHeader("base64_enc", "1");
      },
      cache: false,
      async: false,
      type:"post",
      data:Base64.e64(xml)
    }).responseText;
  if(res==""){
      return null;
  }
  var dataJson = null;
  try{
    eval("dataJson = "+res);
    if(dataJson.status==-99){
      return null;
    }
  }catch(e){}
  return dataJson;
}


/**
 * 提交XML内容并返回XML内容
 * url 提交目标动作路径
 * xml 提交内容
 * base64Enc 提交内容是否经过Base64加密（避免防火墙检查敏感字符）
 */
function queryXml(url,xml,base64Enc){
  var method;
  if(xml){
    method = "POST";
  }else{
    method = "GET";
  }
  if (url.indexOf("?")>-1){
      url+="&";
  }else{
      url+="?";
  }
  url+="_js=1&_ts_="+(new Date()).valueOf();
    var res = $.ajax({
                  type: method,
                  url:url,
                  dataType:"xml",
          beforeSend: function (xhr) {
              if(base64Enc){
                xhr.setRequestHeader("base64_enc", "1");
              }
          },
                  cache: false,
                  async: false,
                  type:"post",
                  data:base64Enc?Base64.e64(xml):xml
             });
    if(res==null){
        return null;
    }
    return $(res.responseXML);
}

/**
 * 调用数据返回Json对象
 * url 调用动作路径
 * params 传入参数
 * reCallFunc 成功回调方法（如果存在该值，则为异步调用）
 * errorFunc  报错回调方法
 * debug 是否输出日志
 */
function getJson(url,params,reCallFunc,errorFunc,debug,reTry,noCheckStatus){
  var method;
  if(params){
    method = "POST";
  }else{
    method = "GET";
  }
  if(url.indexOf("?")>-1){
    url+="&";
  }else{
    url+="?";
  }
  url+="_js=1&_ts_="+(new Date()).valueOf();
  if(reCallFunc){
    $.ajax({
      type     : method,
      url      : url,
      cache    : false,
      dataType : "text",
      data     : params,
      success  : function(result){
                   if(debug){
                     console.log(result);
                   }
                   var dataJson = null;
                   try{
                     eval("dataJson = "+result);
                   }catch(e){}
                   reCallFunc(dataJson);
                 },
      error    : errorFunc
    });
    return;
  }
  var res = $.ajax({
    type: method,
    url: url,
    cache: false,
    async: false,
    data:params
  }).responseText;
  if(debug){
    console.log(res);
  }
  if(res==""){
    return null;
  }
  var dataJson = null;
  try{
    eval("dataJson = "+res);
    if(!noCheckStatus && dataJson.status==-99){
      if(reTry){
        try{
          logout();
        }catch(e){}
        return dataJson;
      }
      if(checkUser()){
        return getJson(url,params,reCallFunc,errorFunc,debug,true);
      }
      return dataJson;
    }
  }catch(e){}
  return dataJson;
}



/**
 * AJAX提交信息
 * url 动作路径
 * params 提交参数字符串 &para1=value1&para2=value2
 * invokeMethod 异步调用时调用成功后执行的方法 如果存在该值，则为异步调用
 * append 是否往底部添加新的内容
 * debug 是否为调试模式
 */
function getUrlValue(url,params,innerTag,invokeMethod,append,debug){
	var method;
	if(params){
		method = "POST";
	}else{
		method = "GET";
	}
  if(innerTag || invokeMethod){
    if(innerTag){
      if(typeof(innerTag)=="string"){
        innerTag = $("#"+innerTag);
      }
      innerTag.append("<div mark=\"_wait_img_\" style=\"width:100%;text-align:center;margin-top:20px;margin-bottom:50px;\"><img src=\"/mnc/images/wait.gif\" /></div>");
    	if(!invokeMethod){
    		invokeMethod = function(data){
              	if(debug){
                 	console.log(data); 
                }
              	innerTag.find("[mark='_wait_img_']").remove();
    			if(append){
    				innerTag.append($(data));
    			}else{
    				innerTag.html(data);
    			}
              	if(typeof(_AfterGetUrlValue)!="undefined"){
                  	_AfterGetUrlValue();
                }
    		}
    	}
    }
    if(debug){
      console.log("准备调用动作:["+url+"] 传入参数:["+params+"] 是否调试模式:["+debug+"]");
    }
    //异步调用
    $.ajax({
      type: method,
      url: url,
      data:params,
      cache: false,
      success: invokeMethod
    });
  }else{
    if(invokeMethod){
      //异步调用
      $.ajax({
        type: method,
        url: url,
        data:params,
        cache: false,
        success: invokeMethod
      });
    }else{
      //同步调用
      return $.ajax({
                  type: method,
                  url: url,
                  cache: false,
                  async: false,
                  data:params
              }).responseText;
    }
  }
}



/**
 * 通过父节点主键获取当前节点的父节点
 * node 当前节点
 * attributeValue 父节点的指定属性的值
 * attributeName 父节点指定的属性名，如果为空，则默认为id
 */
function getParentNode(node,attributeValue,attributeName){
    if(!node){
        return null;
    }
    if (!(node instanceof jQuery)){
        node = $(node);
    }
  if(node[0].nodeName=="#document"){
    return null;
  }
    var res = node.find("["+attributeName+"="+attributeValue+"]");
    if(res.length<1){
        return getParentNode(node[0].parentNode,attributeValue,attributeName);
    }
  return res;
}

/**
 * URL编码转码
 */
function urlEncode(str){      
  var ret="";      
  var strSpecial="!\"#$%&'()*+,/:;<=>?[]^`{|}~%";      
  var tt= "";     
  for(var i=0;i<str.length;i++){      
    var chr = str.charAt(i);      
    var c=str2asc(chr);      
    tt += chr+":"+c+"n";      
    if(parseInt("0x"+c) > 0x7f){      
      ret+="%"+c.slice(0,2)+"%"+c.slice(-2);      
    }else{      
      if(chr==" "){  
        ret+="+";      
      }else if(strSpecial.indexOf(chr)!=-1){     
        ret+="%"+c.toString(16);      
      }else{
        ret+=chr;
      }
    }      
  }      
  return ret;      
}      

/**
 * URL编码解码
 */
function urlDecode(str){      
  var ret="";      
  for(var i=0;i<str.length;i++){      
    var chr = str.charAt(i);      
    if(chr == "+"){      
      ret+=" ";      
    }else if(chr=="%"){      
      var asc = str.substring(i+1,i+3);      
      if(parseInt("0x"+asc)>0x7f){      
        ret+=asc2str(parseInt("0x"+asc+str.substring(i+4,i+6)));      
        i+=5;      
      }else{      
        ret+=asc2str(parseInt("0x"+asc));      
        i+=2;      
      }      
    }else{      
      ret+= chr;      
    }      
  }      
  return ret;      
}      

function str2asc(strstr){ 
  return ("0"+strstr.charCodeAt(0).toString(16)).slice(-2); 
} 
function asc2str(ascasc){ 
  return String.fromCharCode(ascasc); 
} 

/**
 * 主键值容器
 */
function ValueMap(){
        
  var keyList               = new ValueList();     //主键序列
  var vMap                  = ({});                //值容器
  
  this.typeName             = "Map";               //容器名称
  this.put                  = doPut;               //设置值
  this.get                  = doGet;               //获取值
  this.index                = doIndex;             //通过索引值返回指定值（通常用在循环取值）
  this.key                  = doKey;               //通过索引值返回指定主键值
  this.clear                = doClear;             //清除所有值
  this.keys                 = doGetKeys;           //获取所有值主键数组
  this.getKeys              = doGetKeys;           //获取所有值主键数组
  this.remove               = doRemove;            //移除指定值
  this.getKeyString         = doGetKeyString;      //获取主键字符串
  this.getKeyList           = doGetKeyList;        //获取主键序列
  this.toJavaString         = getJavaString;       //获取提交java类的字符串信息
  this.toEncodeJavaString   = getEncodeJavaString; //获取编码后的提交java类的字符串信息
  this.size                 = keyList.size;        //容器中元素数量
  this.putAll               = doPutAll;            //将目标容器中的所有元素装入当前容器中
  this.containsKey          = containsKey;         //判断是否存在该主键
  this.containsValue        = containsValue;       //判断是否存在该值
  this.toString             = doToString;          //获取内容字符串
  this.removeValue          = doRemoveValue;       //移出容器中的值
  this.clone                = doClone;             //复制对象
    
  /*
   * 返回字符串信息
   */
  function doToString(){
     var res = "";
     var keyList = doGetKeyList();
     for(var i=0;i<keyList.size();i++){
         var key = keyList.get(i);
         var value = doGet(key);
         if(value==null){
             res += "["+key+"#null]";
         }else if(value instanceof ValueList){
             res += "["+key+"#List:"+value.toString()+"]";
         }else if(value instanceof ValueList){
             res += "["+key+"#Map:"+value.toString()+"]";
         }else {
              res += "["+key+"#"+value+"]";
         }
         res += "\n";
     }
     res += "{total:"+i+"}\n";
     return res;
  }
    
  /**
   * 克隆方法
   */
  function doClone(){
    var res = new ValueMap();
    var keys = doGetKeys();
    for(var i=0;i<keys.length;i++){
      res.put(keys[i],vMap[keys[i]]);
    }
    return res;
  }
  
  /**
   * 判断是否存在该主键
   * key 指定主键
   */
  function containsKey(key){
      return doGetKeyList().contains(key);
  }
  
  /**
   * 判断是否存在该值
   */
  function containsValue(value){
    for(key in vMap){
      if(vMap[key]==value){
        return true;
      }
    }
    return false;
  }
    
  /**
   * 通过索引值返回指定值
   */
  function doIndex(index){
    return vMap[keyList.get(index)];
  }
  
  /**
   * 通过索引值返回指定主键值
   */
  function doKey(index){
    return keyList.get(index);
  }
    
  /**
   * 将目标容器中的所有元素装入当前容器中 
   * 目标容器
   */
  function doPutAll(map){
      if(map==null || map.typeName!="Map"){
          return;
      }
      var keyList = map.getKeyList();
      if(keyList==null){
          return;
      }
      for(var i=0;i<keyList.size();i++){
          var key = keyList.get(i);
          doPut(key,map.get(key));
      }
  }
    
    
  /**
   * 获取编码后的提交java类的字符串信息
   * @return 提交java类的字符串信息
   */
  function getEncodeJavaString(){
      return urlEncode(getObjectJavaString(this));
  }
  
  /**
   * 获取提交java类的字符串信息
   * @return 提交java类的字符串信息
   */
  function getJavaString(){
      return getObjectJavaString(this);
  }
  
  /**
   * 移除主键值
   * @param key 主键
   */
  function doRemove(key){
      var res = doGet(key);
      vMap[key] = null;
      if (keyList.contains(key)){
          keyList.removeByElement(key);
      }
      return res;
  }
  
  /**
   * 获取容器主键数组
   * @return 主键数组
   */
  function doGetKeys(){
      return keyList.getList();
  }
    
  /**
   * 移出容器中的值
   * 指定值
   */
  function doRemoveValue(value){
    //获取主键序列
    var keyList = doGetKeyList();
    var key; //指定主键
    for(var i=0;i<keyList.size();i++){
      key = keyList.get(i);
      if(doGet(key)==value){
        doRemove(key);
        return key;
      }
    }
  }
  
  /**
   * 获取主键序列
   * @return 主键序列
   */
  function doGetKeyList(){
      return keyList;
  }
  
  /**
   * 清除内容
   */
  function doClear(){
      keyList.clearAll();
      vMap = ({});
  }
  /**
   * 将值放入容器
   * @param key 主键
   * @param value 值
   */
  function doPut(key,value){
      vMap[key] = value;
      if (!keyList.contains(key)){
          keyList.add(key);
      }
  }
    
  /**
   * 取出指定值
   * @param key 主键
   * @return 对应值
   */
  function doGet(key){
    var res = vMap[key];
    if(!res){
      return "";
    }
    return res;
  }
  
  /**
   * 获取主键字符串
   * @return 主键字符串
   */
  function doGetKeyString(){
      return keyList.getListString();
  }
}




/**
 * 序列容器
 * arr 内容数组
 */
function ValueList(arr){

  var listValue           = arr?arr:[];          //核心容器
  var currentPoint        = 0;                   //当前指针位置
  
  this.typeName           = "List";              //容器名称
  this.size               = getSize;             //容器元素数量方法
  this.add                = addElement;          //增加元素方法
  this.removeByElement    = removeByElement;     //移除指定元素
  this.removeByIndex      = removeByIndex;       //通过索引移除指定元素
  this.remove             = removeByIndex;       
  this.get                = getElement;          //获取指定元素
  this.set                = setElement;          //设置指定元素
  this.contains           = containsElement;     //判断指定元素是否存在于序列中
  this.clearAll           = clearAll;            //清空所有元素
  this.clear              = clearAll;            //清空所有元素
  this.getList            = getElementList;      //获取元素数组
  this.getListString      = getElementString;    //获取元素字符串序列
  this.toJavaString       = getJavaString;       //获取提交java类的字符串信息
  this.toEncodeJavaString = getEncodeJavaString; //获取编码后的提交java类的字符串信息
  this.toArray            = doToArray;           //将序列转换为数组
  this.addAll             = doAddAll;            //添加指定序列中的所有元素
  this.toString           = doToString;          //获取内容字符串
  this.setArray           = doSetArray;          //将数组设置到对象中
  this.hasNext            = doHasNext;           //序列中是否存在下一个值
  this.nextValue          = doNextValue;         //获取当前指针所指的位置的值，获取后将指针累加1
  this.value              = doValue;             //当前元素值
  this.replaceValue       = doReplaceValue;      //替换当前元素
  this.sort               = doSort;              //排序
  this.indexOf            = doIndexOf;           //元素在序列中的位置
  this.clone              = doClone;             //执行克隆
    
  /**
   * 替换当前元素
   */
  function doReplaceValue(ele){
    if(getSize()<1 || currentPoint<1 || currentPoint>getSize()){
      return;
    }
    return setElement(currentPoint-1,ele);
  }
  
  /**
   * 执行克隆
   */
  function doClone(){
    //构建返回值
    var res = new ValueList();
    for(var i=0;i<getSize();i++){
      res.add(getElement(i));
    }
    return res;
  }
  
  /**
   * 获取当前元素值
   */
  function doValue(){
    if(getSize()<1){
      return null;
    }else if(currentPoint<1){
      return getElement(0);
    }else if(currentPoint>getSize()){
      return getElement(getSize()-1);
    }
    return getElement(currentPoint-1);
  }
  
    /**
     * 获取当前指针所指的位置的值，获取后将指针累加1
     */
    function doNextValue(){
        return getElement(currentPoint++);
    }
    
    /**
     * 序列中是否存在下一个值
     */
    function doHasNext(){
        if(getSize()>currentPoint){
            return true;
        }
        return false;
    }
    
  
  /**
   * 将数组设置到对象中
   */
  function doSetArray(arr){
    listValue = arr;
    if(arr){
      listValue = arr;
    }else{
      listValue = [];
    }
  }
  
    /*
     * 返回字符串信息
     */
    function doToString(){
       var res = "";
       var size = getSize();
       for(var i=0;i<size;i++){
           var ele = getElement(i);
           if(ele==null){
               res += "[null]";
           }else if(ele instanceof ValueList){
               res += "[List:"+ele.toString()+"]";
           }else if(ele instanceof ValueList){
               res += "[Map:"+ele.toString()+"]";
           }else{
               res += "["+ele+"]";
           }
           res += "\n";
       }
       res += "{total:"+i+"}\n";
       return res;
    }
    
    /**
     * 添加指定序列中的所有元素
     * list 待添加的序列
     */
    function doAddAll(list){
        if(list==null || list.typeName!="List"){
            return; 
        }
        for(var i=0;i<list.size();i++){
            addElement(list.get(i));
        }
    }
    
    /**
     * 将序列转换为数组
     */
    function doToArray(){
        var res = [];
        for(var i=0;i<getSize();i++){
            res[i] = getElement(i);
        }
        return res;
    }
  
    /**
     * 排序
     */
    function doSort(){
      var arr = doToArray();
      arr.sort();
      doSetArray(arr);
    }
    
    /**
     * 返回容器元素数量
     * @return 回容器元素数量
     */
    function getSize(){
        return listValue.length;
    }
    
    /**
     * 获取提交java类的字符串信息
     * @return 提交java类的字符串信息
     */
    function getJavaString(){
        return getObjectJavaString(this);
    }
    
    
    /**
     * 获取提交java类的字符串信息
     * @return 提交java类的字符串信息
     */
    function getEncodeJavaString(){
        return urlEncode(getObjectJavaString(this));
    }
    
    /**
     * 清空所有元素
     */
    function clearAll(){
        listValue = [];
    }
    
    /**
     * 返回指定元素所在序列中的位置
     * @param element 指定元素
     */
    function doIndexOf(element){
      if(!element){
        return -1;
      }
      for(var i=0;i<listValue.length;i++){
        if(listValue[i]==element){
          return i;
        }
      }
      return -1;
    }
    
    /**
     * 增加元素
     * @param element 增加的元素
     * @param index 增加到的位置
     */
    function addElement(element,index){
      if (index==null || index==""){
        listValue[listValue.length] = element;
        return;
      }
      var indexInt; //获取指定索引位置数字
      try{
        indexInt = parseInt(index);
      }catch(e){
        return;
      }
      if(indexInt<0){
        return;
      }
      //将指定位置之后的元素后遗
      var length = listValue.length; //循环索引
      while(length>indexInt){
          listValue[length] = listValue[length-1];
          length--;
      }
      listValue[indexInt] = element;
    }
    
    /**
     * 移除指定的元素
     * 如果容器中有相同的元素存在
     * 则只移除需要由小到大头一个相同的元素
     * @param element 指定的元素
     */
    function removeByElement(element){
        var afterRemoveList = []; //移除元素后的容器
        for(var i=0;i<listValue.length;i++){
            if (listValue[i]==element){
                continue;
            }
            afterRemoveList[afterRemoveList.length]=listValue[i];
        }
        listValue = afterRemoveList;
        return element;
    }
    
    /**
     * 通过元素序号移除指定元素
     * @param index 元素序号
     */
    function removeByIndex(index){
        if(typeof(index) != "number"){
          return removeByElement(index);
        }
        //元素索引数字
        var indexInt;
        try{
            indexInt = parseInt(index);
        }catch(e){
            return null;
        }
        var res = getElement(indexInt);
        var afterRemoveList = []; //移除元素后的容器
        for(var i=0;i<listValue.length;i++){
            if (i==indexInt){
                continue;
            }
            afterRemoveList[afterRemoveList.length]=listValue[i];
        }
        listValue = afterRemoveList;
        return res;
    }
    
    /**
     * 获取元素值
     * @param index 元素索引
   * @param notNull 如果返回值为空，则返回空字符串
     * @return 返回对应元素
     */
    function getElement(index,notNull){
        //元素索引数字
        var indexInt;
        try{
            indexInt = parseInt(index);
        }catch(e){
      if(notNull){
        return "";
      }
            return null;
        }
        try{
      //构建返回值
            var res = listValue[index];
      if(notNull && !res){
        return "";
      }
      return res;
        }catch(e){
      if(notNull){
        return "";
      }
            return null;
        }
    }
  
  /**
   * 将元素替换到指定位置
   */
  function setElement(index,ele){
        //元素索引数字
        var indexInt;
        try{
            indexInt = parseInt(index);
        }catch(e){
            return;
        }
    if(indexInt<1 || indexInt>=getSize()){
      return;
    }
        listValue[index] = ele;
  }
    
    /**
     * 判断元素是否存在与序列中
     * @param element 带判断元素
     * @return tree存在与序列中
     */
    function containsElement(element){
        for(var i=0;i<listValue.length;i++){
            if (listValue[i]==element){
                return true;
            }
        }
        return false;
    }
    
    /**
     * 获取元素数组
     * @return 元素数组
     */
    function getElementList(){
        return listValue;
    }
    
    
    /**
     * 获取元素字符串序列
     * @return 元素字符串序列
     */
    function getElementString(){
        
        //返回值
        var reStr = "";
        for(var i=0;i<listValue.length;i++){
            if (i>0){
                reStr += ",";
            }
            if (listValue[i]!=null){
                reStr += listValue[i];
            }
        }
        return reStr;
    }
}


/**
 * 解析当前页面动作
 */
function parsePage(debug){
   var params = window.location.href;
   var point = params.indexOf("?");
   if(point>-1){
       params = params.substring(point+1,params.length);
   }else{
       params = "";
   }
  var nodes = $("[_execute='js']");
  for(var i=0;i<nodes.length;i++){
    _parseOneNode(nodes[i],params,debug);
  }
}


/**
 * 设置下拉框中的值
 * nodeId 下拉框节点主键或对象
 * data   选项值 [[value,text],[value,text]]
 * defValue 选中默认值
 */
function setArraySelectNode(nodeId,data,defValue){
	if(!nodeId){
		return;
	}
	if(typeof(nodeId)=="string"){
		node = $("#"+nodeId);
	}else{
		node = nodeId;
	}
  var txtData;
  var txt;
	for(var i=0;i<data.length;i++){
    txtData = str(data[i][1]);
    if(txtData!=""){
      txt = "("+data[i][0]+") "+txtData;
    }else{
      txt = data[i][0];
    }
    if(defValue!=null && defValue==data[i][0]){
      node.append($("<option _data_=\"1\" value=\""+data[i][0]+"\" title_value=\""+txtData+"\" selected>"+txt+"</option>"));
    }else{
      node.append($("<option _data_=\"1\" value=\""+data[i][0]+"\" title_value=\""+txtData+"\">"+txt+"</option>"));
    }
	}
}

/**
 * 设置下拉框中的值
 * nodeId 下拉框节点主键或对象
 * debug 是否为调试模式
 */
function setSelectNode(nodeId,debug){
  var node;
  if(!nodeId){
    return;
  }
  if(typeof(nodeId)=="string"){
    node = $("#"+nodeId);
  }else{
    node = nodeId;
  }
  var action = node.attr("_url");
  if(!action){
    return;
  }
  var params = node.attr("_params");
  if(action.substring(0,1)!="/"){
    action = "/"+action;
  }
  var listKey = node.attr("_listkey");
    if(!listKey){
      listKey = ""; 
    }
  var point = action.indexOf("?");
  if(point>-1){
    action = action.substring(0,point)+action.substring(point,action.length);
  }
    if(debug){
       alert("URL:"+action); 
    alert("处理前的下拉框：\n"+node.html());
    }
  //获取动作数据
  var data = getJson(action,params,debug);
  if(data==null){
    return;
  }
    if(listKey!=""){
      var listKeys = listKey.split(".");
      for(var i=0;i<listKeys.length;i++){
        data = data[listKeys[i]];
      }
    }
  if(data && data.rs){
    data = data.rs;
  }
    setSelect(nodeId,data,node.attr("_value"),node.attr("_valueKey"),node.attr("_textKey"));
}


/**
 * 设置下拉框中的值
 * nodeId 下拉框节点主键或对象
 * debug 是否为调试模式
 */
function setSelect(nodeId,data,defValue,valueKey,textKey){
  var node;
  if(!nodeId){
    return;
  }
  if(typeof(nodeId)=="string"){
    node = $("#"+nodeId);
  }else{
    node = nodeId;
  }
    if(!defValue){
      defValue = ""; 
    }
    if(!valueKey){
      valueKey = ""; 
    }
  if(!textKey){
      textKey = "";
    }
    node.find("[_data_='1']").remove();
    if(!data){
      return;
  }
    if(valueKey=="" && textKey==""){
    for(var i=0;i<data.length;i++){
        if(defValue!="" && defValue==data[i]){
          node.append($("<option _data_=\"1\" value=\""+data[i]+"\" selected>"+data[i]+"</option>"));
        }else{
          node.append($("<option _data_=\"1\" value=\""+data[i]+"\">"+data[i]+"</option>"));
        }
    }
    }else{
    for(var i=0;i<data.length;i++){
        if(defValue!="" && defValue==data[i][valueKey]){
          node.append($("<option _data_=\"1\" value=\""+data[i][valueKey]+"\" selected>"+data[i][textKey]+"</option>"));
        }else{
          node.append($("<option _data_=\"1\" value=\""+data[i][valueKey]+"\">"+data[i][textKey]+"</option>"));
        }
    }
    }
}

/**
 * 调用指定动作，并将结果信息设置到指定节点中
 * nodeId 需要设置信息的节点主键或者节点对象
 * action 调用的动作路径
 * params 传入参数
 * debug true是否为调试模式
 */
function parseAction(nodeId,action,params,debug){
  var node;
  if(!nodeId){
    return;
  }
  if(typeof(nodeId)=="string"){
    node = $("#"+nodeId);
  }else{
    node = nodeId;
  }
  if(action.substring(0,1)!="/"){
    action = "/"+action;
  }
  var point = action.indexOf("?");
  if(point>-1){
        action = action.substring(0,point)+(action.indexOf(".ha")<0?".ha":"")+action.substring(point,action.length);
  }else if(action.indexOf(".ha")<0){
    action += ".ha";
  }
    if(debug){
       console.log("URL:"+action); 
    console.log("处理前的HTML模板：\n"+node.html());
    }
  //获取动作数据
  var data = getJson(action,params,debug);
  if(data==null){
      console.log("没有获取到数据:["+action+"] ["+params+"]");
      return;
  }
  var dataEle; //数据元素
  var setNode; //需要设置数据的节点
    for(var key in data){
    setNode = node.find("#"+key);
        if(setNode.length<1){
            setNode = node;
    }
    dataEle = data[key];
    if(dataEle["allcount"]){
      //记录集
      _fixIntoRs(setNode,dataEle);
    }else if(typeof(dataEle)=="string"){
      //设置指定值
      _setNodeValue(setNode,dataEle);
    }else{
      //设置详细信息
      var fields = setNode.find("[_field]");
      for(var j=0;j<fields.length;j++){
        _fixIntoField($(fields[j]),dataEle);
      }
    }
    }
    if(debug){
    console.log("处理后的HTML模板：\n"+node.html());
    }
}

/**
 * 解析其中一个节点
 */
function _parseOneNode(node,params,debug){
  node = $(node);
  var action = node.attr("_action");
  if(!action){
    action = node.attr("_js_action");
    if(!action){
      node.hide();
      return;
    }
  }
  if(debug){
     alert("URL:"+action+"\nparams:"+params); 
  alert("处理前的HTML模板：\n"+node.html());
  }
  //获取动作数据
  var data = getJson(action,params,debug);
  if(data==null){
    return;
  }
  var dataEle; //数据元素
  var setNode; //需要设置数据的节点
    for(var key in data){
    if(node.attr("id")==key){
      setNode = node;
    }else{
      setNode = node.find("#"+key);
    }
        if(setNode.length<1){
      continue;
    }
    dataEle = data[key];
    if(dataEle["allcount"]){
      //记录集
      _fixIntoRs(setNode,dataEle);
    }else if(typeof(dataEle)=="string"){
      //设置指定值
      _setNodeValue(setNode,dataEle);
    }else{
      //设置详细信息
      var fields = setNode.find("[_field]");
      for(var j=0;j<fields.length;j++){
        _fixIntoField($(fields[j]),dataEle);
      }
    }
    }
    if(debug){
    alert("处理后的HTML模板：\n"+node.html());
    }
}


/**
 * 设置记录集到指定节点中
 */
function _fixIntoRs(rsNode,rsData){
  //移除上一次查询的数据（如果存在的话）
  rsNode.find("#tr_data").remove();
  
  //行记录模板
  var trMode = rsNode.find("#tr");
  trMode.hide();
  trMode = trMode.clone();
  trMode.show();
  trMode.attr("id","tr_data");
  
  //记录集
  var rsList = rsData["rs"];
  if(!rsList ||  !rsList.length || rsList.length<1){
    return;
  }
  rsNode.find("#_nodata").remove();
  var tr;
  var fields;
  for(var i=0;i<rsList.length;i++){
    tr = trMode.clone();
    fields = tr.find("[_field]");
    for(var j=0;j<fields.length;j++){
      _fixIntoField($(fields[j]),rsList[i]);
    }
    rsNode.append(tr);
  }
}

/**
 * 将指定数据节点中设置对应的值
 */
function _fixIntoField(fNode,dataMap){
  if(fNode.length<1){
    return;
  }
  var fieldIds = (""+fNode.attr("_field")).split(",");
  var value;
  for(var i=0;i<fieldIds.length;i++){
    if(fieldIds[i]==null || fieldIds[i]==""){
      continue;
    }
    value = dataMap[fieldIds[i]];
    _setNodeValue(fNode,value,i+1);
  }
}

/**
 * 设置指定节点值
 */
function _setNodeValue(fNode,value,index){
  if(fNode.length<1){
    return;
  }
  var nodeName = fNode[0].nodeName;
  if(nodeName){
    nodeName = nodeName.toLowerCase();
  }else{
    nodeName = "";
  }
  if(index==null){
    index = 1;
  }
  var keyWord = fNode.attr("_keyword");
  if(!keyWord){
    keyWord = fNode.attr("_keyword"+index);
  }
  var setValueAttr;
  var checkType = fNode.attr("_checktype");
  if(!checkType){
    setValueAttr = fNode.attr("_checktype"+index);
  }
  if(!checkType){
    checkType = fNode.attr("_check");
  }
  if(!checkType){
    setValueAttr = fNode.attr("_check"+index);
  }
  value = _checkValue(checkType,value,fNode);
  
  setValueAttr = fNode.attr("_set");
  if(!setValueAttr){
    setValueAttr = fNode.attr("_set"+index);
  }
  if(setValueAttr){
    if(keyWord){
      value = (""+fNode.attr(setValueAttr)).replace(keyWord,value);
    }
        if(setValueAttr=="class"){
          fNode.addClass(value);
        }else{
          fNode.attr(setValueAttr,value);
        }
  }else{
    if(nodeName=="input"){
      var atype = fNode.attr("type");
      if(atype){
        atype = atype.toLowerCase();
      }else{
        atype = "text";
      }
      if(atype=="image"){
        fNode.attr("src",value);
      }else if(atype=="checkbox" || atype=="radio"){
        if(fNode.attr("value")==value){
          fNode.attr("checked","checked");
        }else{
          fNode.attr("checked","");
        }
      }else{
        if(keyWord){
          value = (""+fNode.attr("value")).replace(keyWord,value);
        }
        fNode.attr("value",value);
      }
    }else if(nodeName=="select"){
      setSelectNode(fNode); //设置下拉框的值
      //下拉框
      var options = fNode.find("option");
      var opt;
      for(var j=0;j<options.length;j++){
        opt = $(options[j]);
        if(opt.attr("value")==value){
          opt.attr("selected","selected");
          break;
        }
      }
    }else{
      if(keyWord){
        value = (""+fNode.text()).replace(keyWord,value);
      }
      fNode.text(value);
    }
  }
}


/**
 * 根据判断处理值
 */
function _checkValue(checkType,value,node){
  if(!checkType){
    return value;
  }
  if(value==null){
    value = "";
  }
  if (checkType=="date") {
    //只显示年月日
    if (value && value!="") {
      value = formatDate(value,"yyyy-mm-dd");
    }
  }else if(startsWith(checkType,"date:[")) {
        if(value && value!=""){
      //按照指定格式输出年月日
      var format = checkType.substring(6,checkType.length);
      var point = format.lastIndexOf("]"); //分隔符
      if(point>0) {
        format = format.substring(0,point);
          }
      format = trim(format);
      value = formatDate(value,format);
        }
  }else if(checkType=="trim"){
    //去掉首尾空格
    value = trim(value);
  }else if(checkType=="showint"){
    //格式化整型数据  3,124,344,123
    value = addCommas(value);
  }else if(checkType=="time") {
    //只显示小时分秒
    if (value && value!="") {
      value = formatDate(value,"hh:mm:ss");
    }
  }else if(checkType=="datemd") {
    //只显示月日
    if (value && value!="") {
      value = formatDate(value,"mm-dd");
    }
  }else if(checkType.indexOf("switch:")==0) {
    //根据数据值，按照约定替换为指定字符
    //1:是;2:否
    checkType = checkType.substring(7,checkType.length);
    //获取对照表
    var infoMap = fixStringToMap(checkType,";",":");
    if(infoMap.containsKey(value)){
      value = infoMap.get(value);
    }
  }else if (checkType.indexOf("cut:")==0) {
    //cut:20:...   截取前20个字符，并且在尾部加...
    checkType = checkType.substring(4,checkType.length);
    var fength = checkType.indexOf(":");
    //附加字符串
    var addStr = null;
    if (toLength<0) {
      toLength = checkType.length;
      addStr = "";
    }else {
      addStr = checkType.substring(toLength+1,checkType.length);
    }
    //获取截取长度
    var cutPoint = parseInt(checkType.substring(0,toLength));
    //切除超出范围的字符(切除内容不包含html)
    value = cutHtmlString(value,cutPoint,addStr);
  }else if(checkType.indexOf("swap:")==0){
    //swap:3:***** 将结果字符串，从第3个字符后开始的字符，替换成*****
    checkType = checkType.substring(5, checkType.length);
    var toLength = checkType.indexOf(":");
    if(toLength>0) {
      //第n个字符后开始替换
      var startCount = parseInt(checkType.substring(0,toLength));
      checkType = checkType.substring(toLength+1);
      if(value.length>startCount) {
        //整理后的字符串
        var newValue = value.substring(0,startCount);
        value = value.substring(startCount,value.length);
        if(value.length>checkType.length) {
          //实现成 139******001
          value = newValue+checkType+value.substring(checkType.length+value.length);
        }else {
          //长度不够，实现成 139********
          value = newValue+checkType;
        }
      }else {
          //长度完全不够，实现成 **********
                    value = checkType;
      }
    }
  }else if (checkType.indexOf("float:")==0) {
    //处理浮点数  float:16:4  将数字转换为 总长16 小数4位
    //除去float:
    checkType = checkType.substring(6,checkType.length);
    //位置
    var toLength = checkType.indexOf(":");

    var allLength = 0; //整体长度
    var pointLength = 0; //小数点位数
    if (toLength>0) {
      allLength = parseInt(checkType.substring(0,toLength));
      pointLength = parseInt(checkType.substring(toLength+1,checkType.length));
    }else {
      pointLength = parseInt(checkType);
    }
    try {
      value = roundNumber(value,pointLength);
    }catch(e) {
      value = "--";
    }
  }else if(checkType.indexOf("head:")==0) {
    //head:字符串  最终的值为   字符串+字段值
    return checkType.substring(5,checkType.length)+value;
  }else if(checkType.indexOf("foot:")==0) {
    //foot:字符串  最终的值为  字段值+字符串
    return value+checkType.substring(5,checkType.length);
  }else if(checkType=="tohtml") {
    //将文本转换为HTML格式
    return fixHtmlString(value);
  }else if(startsWith(checkType,"if:")) {
    /*
     * if:value{srcattrib:objattrib}  如果数据值为value，则将srcattrib属性名改为objattrib 
     * 或者 if:value{hidden}  如果条件成立，就隐藏  
     * 或者 if:value{!hidden} 如果条件不成立，就隐藏
     * value 前缀  >  大于value时条件生效
     *                  < 小于value时条件生效
     *                  >=  同上，你懂的
     *                  <= 
     *                  <>
     *                  || 被value整除
     *                  (包含的值，用逗号分割)
     * 
     */
    //条件触发
    checkType = checkType.substring(3,checkType.length);
    var point = checkType.lastIndexOf("{"); //检测分隔符
    if(point<0) {
      return null;
    }
    //原属性名
    var srcAttr = checkType.substring(point+1,checkType.length);
    checkType = checkType.substring(0,point);
    //目标属性名
    var objAttr = null;
    point = srcAttr.lastIndexOf("}");
    if(point>0) {
      srcAttr = srcAttr.substring(0,point);
    }
    if(srcAttr.toLowerCase()=="hidden") {
      srcAttr = null;
      objAttr = "hidden";
    }else if(srcAttr.toLowerCase()=="!hidden") {
      srcAttr = "hidden";
      objAttr = null;
    }else {
      point = srcAttr.lastIndexOf(":");
      if(point<0) {
        return null;
      }
      objAttr = srcAttr.substring(point+1,srcAttr.length);
      srcAttr = srcAttr.substring(0,point);
    }
    var checkValue; //检测值
    if(startsWith(checkType,">=")) {
      checkValue = checkType.substring(2,checkType.length);
      if(parseFloat(value)>=parseFloat(checkValue)) {
        if(srcAttr==null) {
          node.hide();
        }else if(objAttr!=null){
          node.removeAttr(objAttr);
          
          node.attr(objAttr,node.attr(srcAttr));
          node.removeAttr(srcAttr);
        }
      }else {
        if(objAttr==null) {
          node.hide();
        }else if(srcAttr!=null) {
          node.removeAttr(srcAttr);
        }
      }
    }else if(startsWith(checkType,"<=")) {
      checkValue = checkType.substring(2,checkType.length);
      if(parseFloat(value)<=parseFloat(checkValue)) {
        if(srcAttr==null) {
          node.hide();
        }else if(objAttr!=null){
          node.removeAttr(objAttr);
          node.attr(objAttr,node.attr(srcAttr));
          node.removeAttr(srcAttr);
        }
      }else {
        if(objAttr==null) {
          node.hide();
        }else if(srcAttr!=null) {
          node.removeAttr(srcAttr);
        }
      }
    }else if(startsWith(checkType,"<")) {
      checkValue = checkType.substring(1,checkType.length);
      if(parseFloat(value)<parseFloat(checkValue)) {
        if(srcAttr==null) {
          node.hide();
        }else if(objAttr!=null){
          node.removeAttr(objAttr);
          node.attr(objAttr,node.attr(srcAttr));
          node.removeAttr(srcAttr);
        }
      }else {
        if(objAttr==null) {
          node.hide();
        }else if(srcAttr!=null) {
          node.removeAttr(srcAttr);
        }
      }
    }else if(startsWith(checkType,">")) {
      checkValue = checkType.substring(1,checkType.length);
      if(parseFloat(value)>parseFloat(checkValue)) {
        if(srcAttr==null) {
          node.hide();
        }else if(objAttr!=null){
          node.removeAttr(objAttr);
          node.attr(objAttr,node.attr(srcAttr));
          node.removeAttr(srcAttr);
        }
      }else {
        if(objAttr==null) {
          node.hide();
        }else if(srcAttr!=null) {
          node.removeAttr(srcAttr);
        }
      }
    }else if(startsWith(checkType,"==")) {
      checkValue = checkType.substring(2,checkType.length);
      if(value==checkValue) {
        if(srcAttr==null) {
          node.hide();
        }else if(objAttr!=null){
          node.removeAttr(objAttr);
          node.attr(objAttr,node.attr(srcAttr));
          node.removeAttr(srcAttr);
        }
      }else {
        if(objAttr==null) {
          node.hide();
        }else if(srcAttr!=null) {
          node.removeAttr(srcAttr);
        }
      }
    }else if(startsWith(checkType,"=")) {
      checkValue = checkType.substring(1,checkType.length);
      if(value==checkValue) {
        if(srcAttr==null) {
          node.hide();
        }else if(objAttr!=null){
          node.removeAttr(objAttr);
          node.attr(objAttr,node.attr(srcAttr));
          node.removeAttr(srcAttr);
        }
      }else {
        if(objAttr==null) {
          node.hide();
        }else if(srcAttr!=null) {
          node.removeAttr(srcAttr);
        }
      }
    }else if(startsWith(checkType,"||")) {
      //是否能被整除
      checkValue = checkType.substring(2,checkType.length);
      var testInt1 = parseInt(value);
      var testInt2 = parseInt(checkValue);
      //整除值
      var testInt = testInt1/testInt2;
      if(testInt1==(testInt2*testInt)) {
        if(srcAttr==null) {
          node.hide();
        }else if(objAttr!=null){
          node.removeAttr(objAttr);
          node.attr(objAttr,node.attr(srcAttr));
          node.removeAttr(srcAttr);
        }
      }else {
        if(objAttr==null) {
          node.hide();
        }else if(srcAttr!=null) {
          node.removeAttr(srcAttr);
        }
      }
    }else if(startsWith(checkType,"(")) {
      //是否包含指定值
      checkValue = checkType.substring(1,checkType.length);
      point = checkValue.lastIndexOf(")");
      if(point<0) {
        return null;
      }
      //包含值序列
      var checkList = new ValueList();
      checkList.setArray(checkValue.substring(0,point).split(","));
      
      if(checkList.contains(value)) {
        if(srcAttr==null) {
          node.hide();
        }else if(objAttr!=null){
          node.removeAttr(objAttr);
          node.attr(objAttr,node.attr(srcAttr));
          node.removeAttr(srcAttr);
        }
      }else {
        if(objAttr==null) {
          node.hide();
        }else if(srcAttr!=null) {
          node.removeAttr(srcAttr);
        }
      }
    }else {
      if(value==checkType) {
        if(srcAttr==null) {
          node.hide();
        }else if(objAttr!=null){
          node.removeAttr(objAttr);
          node.attr(objAttr,node.attr(srcAttr));
          node.removeAttr(srcAttr);
        }
      }else {
        if(objAttr==null) {
          node.hide();
        }else if(srcAttr!=null) {
          node.removeAttr(srcAttr);
        }
      }
    }
    return null;
  }
  return value;
}



/**
 * 按照指定格式，输出日期时间
 * 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符， 
 * 年(y)可以用 1-4 个占位符，毫秒(S)只能用 1 个占位符(是 1-3 位的数字) 
 * yyyy-MM-dd hh:mm:ss.S
 */
function formatDate(dateStr,fmt) {
  var d = new Date(dateStr);
    var o = {
        "M+": d.getMonth() + 1, //月份 
        "o+": d.getMonth() + 1, //月份 （有的js处理时，被强制转换成了小写，导致获取错误的月份）
        "d+": d.getDate(), //日 
        "h+": d.getHours(), //小时 
        "m+": d.getMinutes(), //分 
        "s+": d.getSeconds(), //秒 
        "q+": Math.floor((d.getMonth() + 3) / 3), //季度 
        "n+": d.getMilliseconds(), //毫秒，的浏览器不识别大写
        "S": d.getMilliseconds() //毫秒 
    };
    if (/(y+)/.test(fmt)){
    fmt = fmt.replace(RegExp.$1, (d.getFullYear() + "").substr(4 - RegExp.$1.length));
  }
    for (var key in o){
    if (new RegExp("(" + key + ")").test(fmt)){
      fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[key]) : (("00" + o[key]).substr(("" + o[key]).length)));
    }
  }
    return fmt;
}


/**
 * 去字符串左侧空格
 */
function ltrim(s,f){
  if(!f){
    f = "";
  }
  if(s){
    return s.replace( /^\s*/,f);
  }
  return "";
}

/**
 * 去字符串右侧空格
 */
function rtrim(s,f){
  if(!f){
    f = "";
  }
  if(s){
    return s.replace( /\s*$/,f);
  }
  return "";
}

/**
 * 去字符串两侧空格
 */
function trim(s,f){
  return rtrim(ltrim(s,f),f);
}

/**
 * 将数字从字符串中抽取出来
 */
function innerInt(s){
  if(s){
    s = s.replace(/[^0-9]/ig,"");
    if(s==""){
      return 0;
    }
    return parseInt(s);
  }
  return 0;
}



/**
 * 判断字符串开头是否相同
 * 指定字符串
 * 待判断字符串
 */
/**
 * 判断字符串开头是否相同
 * 指定字符串
 * 待判断字符串
 */
function startsWith(str,substring) {
  if(str==null || substring==null){
    return false;
  }
  if(str.length==substring.length){
    if(str==substring){
      return true;
    }
    return false;
  }
  if(str.substring(0,substring.length)==substring){
    return true;
  }
  return false;
}
String.prototype.startsWith = function(substring){
  if(substring==null){
    return false;
  }
  if(this.length==substring.length){
    if(str==substring){
      return true;
    }
    return false;
  }
  if(this.substring(0,substring.length)==substring){
    return true;
  }
  return false;
}
 
/**
 * 判断字符串末尾是否相同
 * 指定字符串
 * 待判断字符串
 */
function endsWith(str,substring){
  if(str==null || substring==null){
    return false;
  }
  if(str.length==substring.length){
    if(str==substring){
      return true;
    }
    return false;
  }
  if(str.substring(str.length-substring.length,str.length)==substring){
    return true;
  }
  return false;
}
String.prototype.endsWith = function(substring){
  if(substring==null){
    return false;
  }
  if(this.length==substring.length){
    if(this==substring){
      return true;
    }
    return false;
  }
  if(this.substring(this.length-substring.length,this.length)==substring){
    return true;
  }
  return false;
}


/**
 * 数字fgNum位分割
 */
function addCommas(nStr,fgNum){
  if(fgNum==null){
    fgNum = 3;
  }
  nStr += '';
  x = nStr.split('.');
  x1 = x[0];
  x2 = x.length > 1 ? '.' + x[1] : '';
  var rgx = eval("/(\\d+)(\\d{"+fgNum+"})/");
  while (rgx.test(x1)) {
    x1 = x1.replace(rgx, '$1' + ',' + '$2');
  }
  return x1 + x2;
}

/**
 * 将字符串分割为Map格式
 * @param str              字符串    1:是;0:否;:否
 * @param eleSpec     元素分隔符 ;
 * @param keySpec     信息分隔符
 * @return 整理后的容器
 * 2014年3月29日
 * @author 马宝刚
 */
function fixStringToMap(str,eleSpec,keySpec) {
  //构建返回值
  var reMap = new ValueMap();
  if(!str) {
    return reMap;
  }
  str = trim(str);
  if(str.length<1) {
    return reMap;
  }
  //将字符串分割为元素数组
  var eles = str.split(eleSpec);
  var infos = null; //元素信息
  for(var i=0;i<eles.length;i++) {
    infos = eles[i].split(keySpec);
    if(infos.length>1) {
      reMap.put(infos[0],infos[1]);
    }
  }
  return reMap;
}



/**
 * 限制字符串长度（不算html代码）
 * 
 * @author 刘虻 2007-10-15下午08:02:28
 * @param source 源html字符串
 * @param cutSize 限制长度
 * @param footStr 限制后附加字符串
 * @return 处理后的字符串
 */
function cutHtmlString(source,cutSize,footStr) {
  if (!source) {
    return "";
  }
  if (!footStr) {
    footStr = "";
  }
  var length = source.length;
  if (length <= cutSize) {
    return source;
  }
  if (source.indexOf("<") < 0) {
    return source.substring(0, cutSize) + footStr;
  }
  var readPoint = 0;
  // 构造返回值
  var reSbf = "";
  var isAppend = true; // 是否累加
  var notAppendFoot = true; // 是否没放入尾部
  var insideTag = false; // 是否为标签内部
  var onOutTag = false; // 是否为结束字符
  for (var i=0; i<length; i++) {
    // 获取一个字符
    var oneChar = source.substring(i,i+1);
    if (oneChar=="<") {
      insideTag = true;
    }else if(oneChar==">") {
      insideTag = false;
      onOutTag = true;
    }else if(!insideTag) {
      readPoint++;
    }
    if(readPoint>cutSize) {
      if (insideTag) {
        isAppend = true;
      } else {
        isAppend = false;
      }
      if (notAppendFoot) {
        reSbf+=footStr;
        notAppendFoot = false;
      }
    }
    if (isAppend || onOutTag) {
      if (onOutTag) {
        onOutTag = false;
      }
      reSbf+=oneChar;
    }
  }
  return reSbf.replace("<br/>", "").replace("<br>", "");
}

/**
 * 处理小数点位数
 */
function roundNumber(number,decimals) {
  number = parseFloat(number);
    var newString;// The new rounded number  
    decimals = Number(decimals);  
    if (decimals < 1) {  
        newString = (Math.round(number)).toString();  
    } else {  
        var numString = number.toString();  
        if (numString.lastIndexOf(".") == -1) {// If there is no decimal point  
            numString += ".";// give it one at the end  
        }  
        var cutoff = numString.lastIndexOf(".") + decimals;// The point at which to truncate the number  
        var d1 = Number(numString.substring(cutoff,cutoff+1));// The value of the last decimal place that we'll end up with  
        var d2 = Number(numString.substring(cutoff+1,cutoff+2));// The next decimal, after the last one we want  
        if (d2 >= 5) {// Do we need to round up at all? If not, the string will just be truncated  
            if (d1 == 9 && cutoff > 0) {// If the last digit is 9, find a new cutoff point  
                while (cutoff > 0 && (d1 == 9 || isNaN(d1))) {  
                    if (d1 != ".") {  
                        cutoff -= 1;  
                        d1 = Number(numString.substring(cutoff,cutoff+1));  
                    } else {  
                        cutoff -= 1;  
                    }  
                }  
            }  
            d1 += 1;  
        }   
        if (d1 == 10) {  
            numString = numString.substring(0, numString.lastIndexOf("."));  
            var roundedNum = Number(numString) + 1;  
            newString = roundedNum.toString() + '.';  
        } else {  
            newString = numString.substring(0,cutoff) + d1.toString();  
        }  
    }  
    if (newString.lastIndexOf(".") == -1) {// Do this again, to the new string  
        newString += ".";  
    }  
    var decs = (newString.substring(newString.lastIndexOf(".")+1)).length;  
    for(var i=0;i<decimals-decs;i++) newString += "0";  
    //var newNumber = Number(newString);// make it a number if you like  
    document.roundform.roundedfield.value = newString; // Output the result to the form field (change for your purposes)  
}  

/**
 * 处理html内容 将敏感字符替换成安全字符
 * @author 刘虻 2007-10-17下午05:53:03
 * @param html 源html内容
 * @return 处理后的html内容
 */
function fixHtmlString(html) {
  if (!html) {
    return "";
  }
  return html.replace(/&/g, "&amp;").replace(/#/g, "&#35;")
      .replace(/\?/g, "&#63;").replace(/%/g, "&#37;")
      .replace(/</g, "&lt;").replace(/>/g, "&gt;")
      .replace(/ /g, "&nbsp;")
      .replace(/\r\n/g, "<br />")
      .replace(/\r/g, "<br />")
      .replace(/\n/g, "<br />");
}



/**
 * 过滤特殊字符
 * plaintext 过滤前字符
 * 返回 过滤后字符
 */
function urlEncodePro(plaintext){
  if (!plaintext || plaintext==""){
    return "";
  }
  return plaintext
      .replace(/%/g,"%25")
      .replace(/=/g,"%3D")
      .replace(/\+/g,"%2B")
      .replace(/ /g,"+")
      .replace(/\n/g,"%0D%0A")
      .replace(/#/g,"%23")
      .replace(/\'/g,"%27")
      .replace(/\,/g,"%2C")
      .replace(/\"/g,"%22")
      .replace(/\;/g,"%3B")
      .replace(/\./g,"%2E")
      .replace(/\-/g,"%2D")
      .replace(/:/g,"%3A")
      .replace(/\//g,"%2F")
      .replace(/\r/g,"")
      .replace(/\t/g,"%09")
      .replace(/&/g,"%26")
      .replace(/\?/g,"%3F")
      .replace(/!/g,"%21")
      .replace(/</g,"%3C")
      .replace(/>/g,"%3E")
      .replace(/\\/g,"%5C");
}

/**
 * 获取指定节点中的值（类似form提交的值，取自name属性值）
 */
function getFormData(nodeId){
  if(typeof(nodeId)=="string"){
    nodeId = $("#"+nodeId);
  }
  var res = ""; //构建返回值
  var ele;
  var key;
  var value;
  
  //处理input=hidden
  var nodes = nodeId.find("input[type='hidden']");
  for(i=0;i<nodes.length;i++){
    ele = $(nodes[i]);
    key = ele.attr("name");
    if(!key){
      key = ele.attr("id");
    }
    if(!key){
      continue;
    }
    value = ele.val();
    if(res.length>0){
      res += "&";
    }
    res += key+"="+urlEncodePro(value);
  }
  
  //处理input=text
  var nodes = nodeId.find("input[type='text']");
  for(i=0;i<nodes.length;i++){
    ele = $(nodes[i]);
    if(ele.attr("no_submit")=="1"){
      continue;
    }
    key = ele.attr("name");
    if(!key){
      key = ele.attr("id");
    }
    if(!key){
      continue;
    }
    value = ele.val();
    if(res.length>0){
      res += "&";
    }
    res += key+"="+urlEncodePro(value);
  }
  
  //处理input=time
  var nodes = nodeId.find("input[type='time']");
  for(i=0;i<nodes.length;i++){
    ele = $(nodes[i]);
    if(ele.attr("no_submit")=="1"){
      continue;
    }
    key = ele.attr("name");
    if(!key){
      key = ele.attr("id");
    }
    if(!key){
      continue;
    }
    value = ele.val();
    if(res.length>0){
      res += "&";
    }
    res += key+"="+urlEncodePro(value);
  }
  
  //处理input=date
  var nodes = nodeId.find("input[type='date']");
  for(i=0;i<nodes.length;i++){
    ele = $(nodes[i]);
    if(ele.attr("no_submit")=="1"){
      continue;
    }
    key = ele.attr("name");
    if(!key){
      key = ele.attr("id");
    }
    if(!key){
      continue;
    }
    value = ele.val();
    if(res.length>0){
      res += "&";
    }
    res += key+"="+urlEncodePro(value);
  }
  
  //处理input=radio
  nodes = nodeId.find("input[type='radio']");
  for(i=0;i<nodes.length;i++){
    if(!nodes[i].checked){
      continue;
    }
    ele = $(nodes[i]);
    if(ele.attr("no_submit")=="1"){
      continue;
    }
    key = ele.attr("name");
    if(!key){
      key = ele.attr("id");
    }
    if(!key){
      continue;
    }
    value = ele.val();
    if(res.length>0){
      res += "&";
    }
    res += key+"="+urlEncodePro(value);
  }
  
  //处理input=checkbox
  nodes = nodeId.find("input[type='checkbox']");
  for(i=0;i<nodes.length;i++){
    ele = $(nodes[i]);
    if(ele.attr("no_submit")=="1"){
      continue;
    }
    key = ele.attr("name");
    if(!key){
      key = ele.attr("id");
    }
    if(!key){
      continue;
    }
    if(nodes[i].checked){
       value = ele.val();
    }else{
       value = ele.attr("no_check");
       if(!value){
         continue;
       }
    }
    if(res.length>0){
      res += "&";
    }
    res += key+"="+urlEncodePro(value);
  }
  
  //处理select
  nodes = nodeId.find("select");
  for(i=0;i<nodes.length;i++){
    ele = $(nodes[i]);
    if(ele.attr("no_submit")=="1"){
      continue;
    }
    key = ele.attr("name");
    if(!key){
      key = ele.attr("id");
    }
    if(!key){
      continue;
    }
    value = ele.val();
    if(res.length>0){
      res += "&";
    }
    res += key+"="+urlEncodePro(value);
  }
  
  //处理textarea
  nodes = nodeId.find("textarea");
  for(i=0;i<nodes.length;i++){
    ele = $(nodes[i]);
    if(ele.attr("no_submit")=="1"){
      continue;
    }
    key = ele.attr("name");
    if(!key){
      key = ele.attr("id");
    }
    if(!key){
      continue;
    }
    value = ele.val();
    if(res.length>0){
      res += "&";
    }
    res += key+"="+urlEncodePro(value);
  }
  return res;
}




/**
 * 获取指定节点中的值（类似form提交的值，取自name属性值）
 */
function getFormDataObj(nodeId){
  if(typeof(nodeId)=="string"){
    nodeId = $("#"+nodeId);
  }
  var res = {}; //构建返回值
  var ele;
  var key;
  var value;
  
  //处理input=hidden
  var nodes = nodeId.find("input[type='hidden']");
  for(i=0;i<nodes.length;i++){
    ele = $(nodes[i]);
    key = ele.attr("name");
    if(!key){
      key = ele.attr("id");
    }
    if(!key){
      continue;
    }
    value = ele.val();
    res[key] = value;
  }
  
  //处理input=text
  var nodes = nodeId.find("input[type='text']");
  for(i=0;i<nodes.length;i++){
    ele = $(nodes[i]);
    if(ele.attr("no_submit")=="1"){
      continue;
    }
    key = ele.attr("name");
    if(!key){
      key = ele.attr("id");
    }
    if(!key){
      continue;
    }
    value = ele.val();
    res[key] = value;
  }

  //处理input=time
  var nodes = nodeId.find("input[type='time']");
  for(i=0;i<nodes.length;i++){
    ele = $(nodes[i]);
    if(ele.attr("no_submit")=="1"){
      continue;
    }
    key = ele.attr("name");
    if(!key){
      key = ele.attr("id");
    }
    if(!key){
      continue;
    }
    value = ele.val();
    res[key] = value;
  }
  
  //处理input=date
  var nodes = nodeId.find("input[type='date']");
  for(i=0;i<nodes.length;i++){
    ele = $(nodes[i]);
    if(ele.attr("no_submit")=="1"){
      continue;
    }
    key = ele.attr("name");
    if(!key){
      key = ele.attr("id");
    }
    if(!key){
      continue;
    }
    value = ele.val();
    res[key] = value;
  }
  
  //处理input=radio
  nodes = nodeId.find("input[type='radio']");
  for(i=0;i<nodes.length;i++){
    if(!nodes[i].checked){
      continue;
    }
    ele = $(nodes[i]);
    if(ele.attr("no_submit")=="1"){
      continue;
    }
    key = ele.attr("name");
    if(!key){
      key = ele.attr("id");
    }
    if(!key){
      continue;
    }
    value = ele.val();
    res[key] = value;
  }
  
  //处理input=checkbox
  nodes = nodeId.find("input[type='checkbox']");
  for(i=0;i<nodes.length;i++){
    ele = $(nodes[i]);
    if(ele.attr("no_submit")=="1"){
      continue;
    }
    key = ele.attr("name");
    if(!key){
      key = ele.attr("id");
    }
    if(!key){
      continue;
    }
    if(nodes[i].checked){
      value = ele.val();
    }else{
      value = ele.attr("no_check");
      if(!value){
        continue;
      }
    }
    if(res[key]==null || res[key]==""){
      res[key] = value;
    }else{
      res[key] += ","+value;
    }
  }
  
  //处理select
  nodes = nodeId.find("select");
  for(i=0;i<nodes.length;i++){
    ele = $(nodes[i]);
    if(ele.attr("no_submit")=="1"){
      continue;
    }
    key = ele.attr("name");
    if(!key){
      key = ele.attr("id");
    }
    if(!key){
      continue;
    }
    value = ele.val();
    res[key] = value;
  }
  
  //处理textarea
  nodes = nodeId.find("textarea");
  for(i=0;i<nodes.length;i++){
    ele = $(nodes[i]);
    if(ele.attr("no_submit")=="1"){
      continue;
    }
    key = ele.attr("name");
    if(!key){
      key = ele.attr("id");
    }
    if(!key){
      continue;
    }
    value = ele.val();
    res[key] = value;
  }
  return res;
}

//强制转换为字符串
function str(s,defVal){
  if(s){
    return s;
  }
  if(defVal && defVal!=""){
    return defVal;
  }
  return "";
}

//返回当前时间毫秒数
function sid(){
  return ""+(new Date()).getTime();
}

//设置单行记录到指定节点
function setDataById(nodeOrId,data){
  if(typeof(nodeOrId)=="string"){
    nodeOrId = $("#"+nodeOrId);
  }
  clearForm(nodeOrId);
  if(!data){
    return;
  }
  var nodes;
  for(ele in data){
    nodes = nodeOrId.find("#"+ele);
    setNodeValue(nodes,data[ele]);
    
    nodes = nodeOrId.find("[name='"+ele+"']");
    setNodeValue(nodes,data[ele]);
  }
}

//设置值到指定节点中
function setNodeValue(nodeOrId,value){
  if(typeof(nodeOrId)=="string"){
    nodeOrId = $("#"+nodeOrId);
  }
  var nodeName;
  var node;
  var checkType
  var keyword;
  var attrib;
  for(var i=0;i<nodeOrId.length;i++){
    nodeName = nodeOrId[i].nodeName;
    if(!nodeName){
      continue;
    }
    nodeName = nodeName.toLowerCase();
    node = $(nodeOrId[i]);
    
    checkType = node.attr("_checktype");
    if(!checkType){
      checkType = node.attr("_check");
    }
    if(checkType){
      _checkValue(checkType,value,node)
    }
    keyword = node.attr("keyword");
    if(!keyword){
      keyword = node.attr("kw");
    }
    
    if(nodeName=="input"){
      attrib = node.attr("type");
      if(!attrib){
        continue;
      }
      attrib = attrib.toLowerCase();
      if(attrib=="text" || attrib=="time" || attrib=="date" || attrib=="hidden"){
        if(keyword){
          value = (""+node.val()).replace(keyword,value);
        }
        node.val(value);
      }else if(attrib=="checkbox" || attrib=="radio"){
        if(node.attr("value")==value){
          node.prop("checked",true);
        }else{
          node.prop("checked",false);
        }
      }
    }else if(nodeName=="select" || nodeName=="textarea"){
      if(keyword){
        value = (""+node.val()).replace(keyword,value);
      }
      node.val(value);
    }else{
      attrib = node.attr("_set");
      if(attrib){
        if(keyword){
          value = (""+node.attr(attrib)).replace(keyword,value);
        }
        node.attr(attrib,value);
      }else{
        if(keyword){
          value = (""+node.html()).replace(keyword,value);
        }
        node.html(value);
      }
    }
  }
}

//清除指定节点中所有需要输入的对象值
//注意：如果隐藏输入框标记为 def="1" 则不被清空
function clearForm(nodeOrId){
  if(typeof(nodeOrId)=="string"){
    nodeOrId = $("#"+nodeOrId);
  }
  //处理input=hidden
  var nodes = nodeOrId.find("input[type='hidden'][def!='1']");
  if(nodes.length>0){
    nodes.val("");
  }
  //处理input=text
  var nodes = $("input[type='text']");
  if(nodes.length>0){
    nodes.val("");
  }
  //处理input=time
  nodes = $("input[type='time']");
  if(nodes.length>0){
    nodes.val("");
  }
  //处理input=date
  nodes = $("input[type='date']");
  if(nodes.length>0){
    nodes.val("");
  }
  //处理input=radio
  nodes = $("input[type='radio']");
  if(nodes.length>0){
    nodes.prop("checked",false);
  }
  //处理input=checkbox
  nodes = $("input[type='checkbox']");
  if(nodes.length>0){
    nodes.prop("checked",false);
  }
  //处理select
  nodes = $("select");
  if(nodes.length>0){
    nodes.val("");
  }
  //处理textarea
  nodes = $("textarea");
  if(nodes.length>0){
    nodes.val("");
  }
}

//设置cookie
function cookie(key,value,sec){
  if(!sec){
    sec = 1000*60*60*24*365;
  }else{
    sec = sex*1000;
  }
  var exp = new Date();
  exp.setTime(exp.getTime() + sec);
  document.cookie = key + "="+ escape (value) + ";expires=" + exp.toGMTString();
}

//删除cookie
function cookieDel(key){
  var exp = new Date();
  //将date设置为过去的时间
  exp.setTime(exp.getTime()-10000);
  document.cookie=key+"=; expire="+exp.toGMTString();
}

//读取cookie
function cookie(key){
  var arr,reg=new RegExp("(^| )"+key+"=([^;]*)(;|$)");
  if(arr=document.cookie.match(reg)){
    return unescape(arr[2]);
  }
  return "";
}


/**
 * 设置外部宽度
 */
function setOuterWidth(node,width){
  if(!node){
    return;
  }
  var outerWidth = 
        innerInt(node.css("margin-left"))
      + innerInt(node.css("margin-right"))
      + innerInt(node.css("padding-left"))
      + innerInt(node.css("padding-right"))
      + innerInt(node.css("border-left-width"))
      + innerInt(node.css("border-right-width"));
  width -= outerWidth;
  if(width<0){
    width = 0;
  }
  node.width(width);
  
}

/**
 * 返回指定节点占用高度（包括border宽度，margin padding）
 */
function outerHeight(jqNode){
  var height;
  if(jqNode.length>0 && jqNode[0].scrollHeight){
    height = jqNode[0].scrollHeight;
  }else {
    height = jqNode.height();
  }
  return   innerInt(jqNode.css("margin-top"))
          +innerInt(jqNode.css("padding-top"))
          +innerInt(jqNode.css("border-top-width"))
          +height
          +innerInt(jqNode.css("margin-bottom"))
          +innerInt(jqNode.css("padding-bottom"))
          +innerInt(jqNode.css("border-bottom-width"));
}

/**
 * 返回指定节点占用宽度（包括border宽度，margin padding）
 */
function outerWidth(jqNode){
  var width;
  if(jqNode.length>0 && jqNode[0].scrollWidth){
    width = jqNode[0].scrollWidth;
  }else {
    width = jqNode.width();
  }
  return   innerInt(jqNode.css("margin-left"))
          +innerInt(jqNode.css("padding-left"))
          +innerInt(jqNode.css("border-left-width"))
          +width
          +innerInt(jqNode.css("margin-right"))
          +innerInt(jqNode.css("padding-right"))
          +innerInt(jqNode.css("border-right-width"));
}

/**
 * 设置外部高度
 */
function setOuterHeight(node,height){
  if(!node){
    return;
  }
  var outerHeight = 
        innerInt(node.css("margin-top"))
      + innerInt(node.css("margin-bottom"))
      + innerInt(node.css("padding-top"))
      + innerInt(node.css("padding-bottom"))
      + innerInt(node.css("border-top-width"))
      + innerInt(node.css("border-bottom-width"));
  height -= outerHeight;
  if(height<0){
    height = 0;
  }
  node.height(height);
}


//当前时间
function now(){
  var date = new Date();
  var res = date.getFullYear()+"-";
  var val = date.getMonth()+1;
  if(val<10){
   res += "0"+val; 
  }else{
    res += val;
  }
  res += "-";
  val = date.getDate();
  if(val<10){
    res += "0"+val;
  }else{
    res += val;
  }
  res += " ";
  val = date.getHours();
  if(val<10){
    res += "0"+val;
  }else{
    res += val;
  }
  res += ":";
  val = date.getMinutes();
  if(val<10){
    res += "0"+val;
  }else{
    res += val;
  }
  res += ":";
  val = date.getSeconds();
  if(val<10){
    res += "0"+val;
  }else{
    res += val;
  }
  return res;
}

/////////////////////////////////////////////////
//本地会话数据库

//写入、读取、删除
function sdata(key,value,del){
  if(!sessionStorage){
    return "";
  }
  if(del){
    if(key){
      value = str(sessionStorage.getItem(key));
      sessionStorage.removeItem(key);
    }else{
      sessionStorage.clear();
      value = "";
    }
    return value;
  }
  if(value && value!=""){
    sessionStorage.setItem(key,value);
  }else{
    value = str(sessionStorage.getItem(key));
  }
  return value;
}

/////////////////////////////////////////////////
//本地简单永久数据库

//写入、读取、删除
function ldata(key,value,del){
  if(!localStorage){
    return "";
  }
  if(del){
    if(key){
      value = str(localStorage.getItem(key));
      localStorage.removeItem(key);
    }else{
      localStorage.clear();
      value = "";
    }
    return value;
  }
  if(value && value!=""){
    localStorage.setItem(key,value);
  }else{
    value = str(localStorage.getItem(key));
  }
  return value;
}
/////////////////////////////////////////////////

//获取当前点击事件 IE严格模式不支持 .caller
//function getEvent(){
//  if(window.event){
//    return window.event;
//  }
//  var func = getEvent.caller;
//  while(func != null){
//    var arg0 = func.arguments[0];
//    if(arg0){
//      if((arg0.constructor==Event || arg0.constructor ==MouseEvent
//            || arg0.constructor==KeyboardEvent)
//            ||(typeof(arg0)=="object" && arg0.preventDefault
//                && arg0.stopPropagation)){
//        return arg0;
//      }
//    }
//    func = func.caller;
//  }
//  return null;
//}
function getEvent(){
  if(window.event){
    return window.event;
  }
  return null;
}

//终止事件冒泡
function stopEvent(evt){
  if(!evt){
    evt = getEvent();
  }
  if(!evt){
    return;
  }
  if(evt.preventDefault){
    // Firefox    
    evt.preventDefault();
    evt.stopImmediatePropagation();
  } else {
    // IE
    evt.cancelBubble = true;
    evt.returnValue  = false;
  } 
}

//获取样式信息值中的数字
function cssNum(str){
  var res = parseFloat((str+"").replace(/[^\d.]/g,""));
  if(res){
    return res;
  }
  return 0;
}

//str为样式值，可以是px，可以是百分比。如果是百分比
//则与totalValue相乘返回结果值
//lastSuffix 返回值是否带后缀
function cssValue(str,totalValue,lastSuffix){
  if(!str || str.length<1){
    if(lastSuffix){
      return "0px";
    }
    return 0;
  }
  str = (str+"").toLowerCase();
  if(endsWith(str,"px")){
    if(lastSuffix){
      return str;
    }
    return parseFloat(str.substr(0,str.length-2));
  }else if(endsWith(str,"%")){
    //百分比
    str = parseFloat(str.substr(0,str.length-1));
    if(totalValue){
      totalValue = cssNum(totalValue)/100;
      if(lastSuffix){
        return (totalValue*str)+"px";
      }
      return totalValue*str;
    }
    if(lastSuffix){
      return str+"px";
    }
    return str;
  }
  if(lastSuffix){
    return str+"px";
  }
  return parseFloat(str.replace(/[^\d.]/g,""));
}


//手机中可以实现双击，三击事件
function clickEvent(node,triggerCount,method,delayTime){
  var evt = getEvent();
  stopEvent(evt);
  if(!(node instanceof jQuery)){
    node = $(node);
  }
  if(!delayTime){
    delayTime = 400;
  }
  var timeOutHandle = node.attr("_time_out_handle");
  if(timeOutHandle){
    node.removeAttr("_time_out_handle");
    window.clearTimeout(timeOutHandle);
  }
  var clickCount = node.attr("_click_count");
  if(clickCount){
    clickCount++;
  }else{
    clickCount = 1;
  }
  node.attr("_click_count",clickCount);
  window.setTimeout(function(){
    timeOutHandle = _doClickEvent(node,triggerCount,method);
    node.attr("_time_out_handle",timeOutHandle);
  },delayTime); 
}

function _doClickEvent(node,triggerCount,method){
  var clickCount = node.attr("_click_count");
  node.removeAttr("_click_count");
  if(!method || clickCount!=triggerCount){
    return;
  }
  method(node);
}

/**
 * 生成唯一主键值（毫秒级 同一毫秒多次调用时，值会重复）
 */
var NID_INDEX_VALUE = 0;
function nid(){
  var day = new Date();
  var res = "JS"+day.getFullYear(); //6
  var value = day.getMonth() + 1; //8
  if(value<10){
    res += "0"+value;
  }else{
    res += value;
  }
  value = day.getDate(); //10
  if(value<10){
    res += "0"+value;
  }else{
    res += value;
  }
  value = day.getHours(); //12
  if(value<10){
    res += "0"+value;
  }else{
    res += value;
  }
  value = day.getMinutes(); //14
  if(value<10){
    res += "0"+value;
  }else{
    res += value;
  }
  value = day.getSeconds(); //16
  if(value<10){
    res += "0"+value;
  }else{
    res += value;
  }
  if(NID_INDEX_VALUE>=9999){
    NID_INDEX_VALUE = 0;
  }
  value = ""+(NID_INDEX_VALUE++);
  while(value.length<4){
    value = "0"+value;
  }
  return res+value;
}




/**
 * 处理自动宽度和高度
 * 
 * 节点属性： 
 *            swidth 值： 10px（固定值）  10%（剩余宽度的百分比值）   无值：（剩余宽度）
 *           sheight 值： 10px（固定值）  10%（剩余宽度的百分比值）   无值：（剩余宽度）
 */
var FIX_AUTO_SIZE_SN = 0;
function fixAutoSize(node){
  if(FIX_AUTO_SIZE_SN>9999){
    FIX_AUTO_SIZE_SN = 0;
  }else{
    FIX_AUTO_SIZE_SN++;
  }
  if(!node){
    node = $("html");
  }
  fixAutoWidth(node,FIX_AUTO_SIZE_SN);
  fixAutoHeight(node,FIX_AUTO_SIZE_SN);
}

//执行处理需要补全宽度的节点
function doFixWidth(node,sn){
  if(node.attr("sn_auto_swidth")==sn){
    return; //该节点宽度已经处理过了
  }
  node.attr("sn_auto_swidth",sn);
  
  //判断当前节点所在的父节点，是否存在这个标记
  var pNode = findPNode(node,"swidth",sn);
  if(pNode){
    doFixWidth(pNode,sn);
  }
  var pWidth = node.width(); //总宽度
  if(!pWidth || pWidth==0){
    pWidth = WIDTH;
  }
  var lessWidth = pWidth;    //剩余宽度
  var width;
  var mLeft;
  var mRight;
  var pLeft;
  var pRight;
  var borderVal;
  var eNode;
  var noList  = new ValueList();  //没有设置宽度值的节点序列
  node.find(">").each(function(){
    eNode     = $(this);
    if(eNode.attr("no_swidth")!=undefined){
      return;
    }
    if(eNode.css("position")=="absolute"){
      return;
    }
    if(eNode.css("display")=="none"){
      return;
    }
    width    = str(this.style.width);
    if(width=="" || eNode.attr("swidth_no_set")=="1"){
      noList.add(eNode);
      return;
    }
    mLeft     = cssValue(eNode.css("margin-left"));
    mRight    = cssValue(eNode.css("margin-right"));
    pLeft     = cssValue(eNode.css("padding-left"));
    pRight    = cssValue(eNode.css("padding-right"));
    borderVal = cssValue(eNode.css("border-left-width"))+cssValue(eNode.css("border-right-width"));
    
    lessWidth -= cssValue(width,pWidth)+mLeft+mRight+pLeft+pRight+borderVal;
  });
  
  var noListSize = noList.size();
  var average    = lessWidth/noListSize;
  for(var i=0;i<noListSize;i++){
    eNode = noList.get(i);
    eNode.attr("swidth_no_set","1");
    mLeft      = cssValue(eNode.css("margin-left"));
    mRight     = cssValue(eNode.css("margin-right"));
    pLeft      = cssValue(eNode.css("padding-left"));
    pRight     = cssValue(eNode.css("padding-right"));
    borderVal  = cssValue(eNode.css("border-left-width"))+cssValue(eNode.css("border-right-width"));
    
    if(i+1==noListSize){
      width       = lessWidth-mLeft-mRight-pLeft-pRight-borderVal;
    }else{
      width       = average-mLeft-mRight-pLeft-pRight-borderVal;
      lessWidth  -= average;
    }
    eNode.width(width);
  }
}


/**
 * 处理自动宽度
 */
function fixAutoWidth(pNode,sn){
  pNode.find("[swidth]").each(function(){
    doFixWidth($(this),sn);
  });
}


//判断当前节点的父节点（父节点的父节点）是否存在指定属性，
function findPNode(node,key,sn){
  var pNode = node.parent();
  if(pNode.length<1 || pNode[0].nodeName=="HTML"){
    return null;
  }
  if(pNode.attr(key)!=undefined && pNode.attr("sn_auto_"+key)!=sn){
    return pNode;
  }
  return findPNode(pNode,key,sn);
}


//执行处理需要补全高度的节点
function doFixHeight(node,sn){
  
  if(node.attr("sn_auto_sheight")==sn){
    return; //该节点高度已经处理过了
  }
  node.attr("sn_auto_sheight",sn);
  
  //判断当前节点所在的父节点，是否存在这个标记
  var pNode = findPNode(node,"sheight",sn);
  if(pNode){
    doFixHeight(pNode,sn);
  }
  var pHeight = node.height(); //总高度
  if(!pHeight || pHeight==0){
    pHeight = HEIGHT;
  }
  var lessHeight = pHeight;    //剩余高度
  var height;
  var mTop;
  var mBottom;
  var pTop;
  var pBottom;
  var borderVal;
  var eNode;
  var parentMTop;
  var noList  = new ValueList();  //没有设置高度值的节点序列
  var peNode;
  node.find(">").each(function(){
    eNode     = $(this);
    if(eNode.attr("no_sheight")!=undefined){
      return;
    }
    if(eNode.css("position")=="absolute"){
      return;
    }
    if(eNode.css("display")=="none"){
      return;
    }
    height    = str(this.style.height);
    if(height=="" || eNode.attr("sheight_no_set")=="1"){
      noList.add(eNode);
      return;
    }
    mTop      = cssValue(eNode.css("margin-top"));
    mBottom   = cssValue(eNode.css("margin-bottom"));
    pTop      = cssValue(eNode.css("padding-top"));
    pBottom   = cssValue(eNode.css("padding-bottom"));
    borderVal = cssValue(eNode.css("border-top-width"))+cssValue(eNode.css("border-bottom-width"));
    peNode    = eNode.parent();
    
    //如果当前节点设置了margin-top并且父节点也设置了margin-top
    //当前节点并不是在父节点内部上方空出指定值，而是占用了父节点 
    //的margin-top值，比如父节点的这个值为20，当前节点的这个值为10
    //则当前节点的这个值并没有占用父节点内部高度
    if(peNode.find(">")[0]==this && peNode.css("overflow")!="hidden"){
      parentMTop = cssValue(peNode.css("margin-top"));
      if(parentMTop>0){
        mTop = mTop-parentMTop;
        if(mTop<0){
          mTop = 0;
        }
      }
    }
    
    lessHeight -= cssValue(height,pHeight)+mTop+mBottom+pTop+pBottom+borderVal;
    //console.log("AutoHeight:Set:  Node:["+this.nodeName+"] ID:["+this.id+"] Class:["+this.className+"] 父节点高度:["
    //  +pHeight+"] 当前节点纯高度:["+cssValue(height,pHeight)+"] 剩余高度:["+lessHeight+"] 顶部外边界:["
    //  +mTop+"] 底部外边界:["+mBottom+"] 顶部内边界:["+pTop+"] 底部内边界:["+pBottom+"] 边框值:["+borderVal+"]\n");
  });
  
  var noListSize = noList.size();
  var average    = lessHeight/noListSize;
  for(var i=0;i<noListSize;i++){
    eNode = noList.get(i);
    eNode.attr("sheight_no_set","1");
    mTop      = cssValue(eNode.css("margin-top"));
    mBottom   = cssValue(eNode.css("margin-bottom"));
    pTop      = cssValue(eNode.css("padding-top"));
    pBottom   = cssValue(eNode.css("padding-bottom"));
    borderVal = cssValue(eNode.css("border-top-width"))+cssValue(eNode.css("border-bottom-width"));
    peNode    = eNode.parent();

    //如果当前节点设置了margin-top并且父节点也设置了margin-top
    //当前节点并不是在父节点内部上方空出指定值，而是占用了父节点 
    //的margin-top值，比如父节点的这个值为20，当前节点的这个值为10
    //则当前节点的这个值并没有占用父节点内部高度
    if(peNode.find(">")[0]==eNode[0] && peNode.css("overflow")!="hidden"){
      parentMTop = cssValue(peNode.css("margin-top"));
      if(parentMTop>0){
        mTop = mTop-parentMTop;
        if(mTop<0){
          mTop = 0;
        }
      }
    }
    
    if(i+1==noListSize){
      height      = lessHeight-mTop-mBottom-pTop-pBottom-borderVal;
      //console.log("AutoHeightLast:NoSet:  Node:["+eNode[0].nodeName+"] ID:["+eNode[0].id+"] Class:["+this.className+"] 父节点高度:["+pHeight
      //  +"] 当前节点纯高度:["+height+"] 剩余高度:["+lessHeight+"] 顶部外边界:["+mTop+"] 底部外边界:["+mBottom+"] 顶部内边界:["
      //  +pTop+"] 底部内边界:["+pBottom+"] 边框值:["+borderVal+"]\n");
    }else{
      height      = average-mTop-mBottom-pTop-pBottom-borderVal;
      //console.log("AutoHeightMore:NoSet:  Node:["+eNode[0].nodeName+"] ID:["+eNode[0].id+"] Class:["+this.className+"] 父节点高度:["+pHeight
      //  +"] 当前节点纯高度:["+height+"] 剩余高度:["+average+"] 顶部外边界:["+mTop+"] 底部外边界:["+mBottom+"] 顶部内边界:["+pTop
      //  +"] 底部内边界:["+pBottom+"] 边框值:["+borderVal+"]\n");
      lessHeight -= average;
    }
    eNode.height(height);
  }
}


/**
 * 处理自动高度
 */
function fixAutoHeight(pNode,sn){
  pNode.find("[sheight]").each(function(){
    doFixHeight($(this),sn);
  });
}


//激活指定动态加载内容的节点中的样式信息激活
//link rel="stylesheet"
function activeCss(node){
  if(!node){
    return;
  }
  node.find("link").each(function(){
    var lNode = $(this);
    if(lNode.attr("type")!="text/css"){
      return;
    }
    loadCss(lNode.attr("href"));
  });
}

//动态加载样式表
function loadCss(path,reload,id,doc){
  if(!doc){
    doc = window.document;
  }
  var hasExist = false;
  var head = $(doc).find("head");
  if(id){
    var node = head.find("#skin_css");
    if(node.length<1){
      head.append([
         '<link rel="stylesheet" type="text/css" media="screen" href="'
        ,path
        ,'" id="',id,'"/>'
      ].join(''));
    }else if(reload){
      node.attr("href",path);
    }
    return;
  }
  head.find("link").each(function(){
    var node = $(this);
    if(node.attr("type")!="text/css"){
      return;
    }
    if(node.attr("href")==path){
      if(reload){
        node.remove();
      }else{
        hasExist = true;
      }
    }
  });
  if(hasExist){
    return;
  }
  head.append([
     '<link rel="stylesheet" type="text/css" media="screen" href="'
    ,path
    ,'" />'
  ].join(''));
}

//激活指定动态加载内容的节点中的脚本信息激活
function activeScript(node){
  var sList      = new ValueList();
  var deferSList = new ValueList();
  node.find("script").each(function(){
    var sNode = $(this);
    var src = sNode.attr("src");
    if(!src || src==""){
      return;
    }
    if(sNode.prop("defer")){
      deferSList.add(src);
    }else{
      sList.add(src);
    }
  });
  for(var i=0;i<sList.size();i++){
    loadScript(sList.get(i));
  }
  for(var i=0;i<deferSList.size();i++){
    loadScript(deferSList.get(i));
  }
}

//加载指定脚本
function loadScript(path,afterEvt){
  //执行加载脚本
  //console.debug("----------动态加载脚本：["+path+"]");
  jQuery.getScript(path,afterEvt);
}

//除去空对象元素
function fixArrayEmpty(arrs){
  var res = {};
  if(arrs){
    for(var key in arrs){
      if(arrs[key]===null || arrs[key]===undefined || arrs[key]===""){
        continue;
      }
      res[key] = arrs[key];
    }
  }
  return res;
}

//返回指定节点的绝对位置。这个节点在iframe中，也会返回当前浏览器的绝对位置
//node   指定节点
//win    节点所在的window对象
//popWin 在指定的window对象中的定位
//[left,top]
function getAbsPosition(node,win,popWin){
  if(!win){
    win = window;
  }
  if(!popWin){
    popWin = win;
  }
  if(!node){
    return [0,0];
  }else if(typeof(node)=="string"){
    node = $(node);
    if(node.length<1){
      return [0,0];
    }
  }else if(!(node instanceof jQuery)){
    node = $(node);
    if(node.length<1){
      return [0,0];
    }
  }
  var offset = node.offset();
  var body   = node.parents("body")[0];
  var res = [offset.left+body.scrollLeft,offset.top+body.scrollTop];
  
  if(win!=popWin){
     for(var i=0;i<win.parent.frames.length;i++){
       if(win.parent.frames[i]==win){
         var pRes = getAbsPosition(win.parent.frames[i].frameElement,win.parent,popWin);
         res[0] = res[0]+pRes[0];
         res[1] = res[1]+pRes[1];
       }
     }
  }
  return res;
}

//获取当前iframe中窗口包含父窗口的scrollLeft合计
function getScrollLeft(win){
  if(win==null){
    return 0;
  }
  var val = win.document.body.scrollLeft;
  if(win.parent!=null && win.parent!=win){
    val += getScrollLeft(win.parent);
  }
  return val;
}

//获取当前iframe中窗口包含父窗口的scrollTop合计
function getScrollTop(win){
  if(win==null){
    return 0;
  }
  var val = win.document.body.scrollTop;
  if(win.parent!=null && win.parent!=win){
    val += getScrollTop(win.parent);
  }
  return val;
}



/**
 * ajax方式下载文件
 * @param url 调用目标路径
 * @param post 提交数据
 * @param readyChangeEvent 准备下载时调用的事件
 */
function download(url,post,fileName,readyChangeEvent){
  //构建XMLHttpRequest下载文件
  var xmlHttp;
  if (window.XMLHttpRequest){
      //  IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
      xmlHttp=new XMLHttpRequest();
  }else{
      // IE6, IE5 浏览器执行代码
      xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
  if(post && post!=""){
    xmlHttp.open("POST",url,true);
  }else{
    xmlHttp.open('GET',url,true);
  }
  xmlHttp.setRequestHeader("CONTENT-TYPE", "application/x-www-form-urlencoded");
  xmlHttp.responseType = "blob"; // 返回类型blob
  //定义请求完成的处理函数，请求前也可以增加加载框/禁用下载按钮逻辑
  xmlHttp.onload = function () {
    //请求完成
    if(this.status===200) {
      //返回200
      var blob   = this.response;
      if( window.navigator &&  window.navigator.msSaveBlob){
        window.navigator.msSaveBlob(blob, fileName);
      }else{
        var reader = new FileReader();
        reader.readAsDataURL(blob);  //转换为base64，可以直接放入a表情href
        reader.onload = function (e) {
          //转换完成，创建一个a标签用于下载
          var aNode = document.createElement('a');
          aNode.download = fileName;
          aNode.href = e.target.result;
          $("body").append(aNode); //修复firefox中无法触发click
          aNode.click();
          $(aNode).remove();
        }
      }
    }
  };
  if(readyChangeEvent){
    xmlHttp.onreadystatechange = function() {
	    if(xmlHttp.readyState == 4) {
	      readyChangeEvent();
	    }
    }
  }
  if(post && post!=""){
    xmlHttp.send(post);
  }else{
    xmlHttp.send(null);
  }
}

//返回当前日期字符串
function today(){
  var d = new Date();
  var month = d.getMonth()+1;
  var day   = d.getDate();
  return d.getFullYear()+"-"+(month<10?"0"+month:month)+"-"+(day<10?"0"+day:day);
}

//阻止冒泡事件
function stopBubble(e) { 
  //如果提供了事件对象，则这是一个非IE浏览器 
  if ( e && e.stopPropagation ) {
      //因此它支持W3C的stopPropagation()方法 
      e.stopPropagation(); 
  }else {
      //否则，我们需要使用IE的方式来取消事件冒泡 
      window.event.cancelBubble = true; 
  }
}

//将src中的值设置到obj中，
//调用方法： obj = setVar(src);
//如果obj中也存在值，并且以obj中的值为准，用src中的值补全obj中不存在的值： obj = setVar(src,obj);
function setVar(src,obj){
  if(src==null){
    return;
  }
  if(Array.isArray(src)){
    if(!Array.isArray(obj)){
      obj = [];
    }
    setArray(src,obj);
    return obj;
  }
  var keys = Object.keys(src);
  if(keys.length<1){
    return src;
  }
  var okeys = obj==null?[]:Object.keys(obj);
  if(okeys.length<1){
    obj = {};
  }
  setObject(src,obj);
  return obj;
}

//将src对象中的值设置到obj对象中（src和obj必须都是{}对象。该方法不能直接调用，请用setVar)
function setObject(src,obj){
  if(src==null || obj==null){
    return;
  }
  var keys = Object.keys(src);
  var srcVal;
  var objVal;
  for(var i=0;i<keys.length;i++){
    srcVal = src[keys[i]];
    if(srcVal==null){
      continue;
    }
    objVal = obj[keys[i]];
    if(typeof(srcVal)=="string"){
      if(objVal==null){
        obj[keys[i]] = srcVal;
      }
      continue;
    }
    if(Array.isArray(srcVal)){
      if(objVal==null || !Array.isArray(objVal)){
        objVal = [];
        obj[keys[i]] = objVal;
      }
      setArray(srcVal,objVal);
    }else{
      var cKeys = null;
      if(srcVal){
        try{
          cKeys = Object.keys(srcVal);
        }catch(e){}
      }
      if(cKeys==null || cKeys.length<1){
        if(objVal==null){
          obj[keys[i]] = srcVal;
        }
      }else{
        if(objVal==null){
          objVal = {};
          obj[keys[i]] = objVal;
        }else{
          var coKey = objVal==null?[]:Object.keys(objVal);
          if(coKey.length<1){
            objVal = {};
            obj[keys[i]] = objVal;
          }
        }
        setObject(srcVal,objVal);
      }
    }
  }
}

//将src数组中的值设置到obj数组中（src和obj必须都是数组。该方法不能直接调用，请用setVar)
function setArray(src,obj){
  if(src==null || obj==null 
       || !Array.isArray(src) || !Array.isArray(obj)){
    return;
  }
  var keys;
  var objEle;
  for(var i=0;i<src.length;i++){
    if(src[i]==null){
      continue;
    }
    if(typeof(src[i])=="string"){
      obj.push(src[i]);
      continue;
    }
    if(Array.isArray(src[i])){
      objEle = [];
      obj.push(objEle);
      setArray(src[i],objEle);
      continue;
    }
    keys = src[i]==null?[]:Object.keys(src[i]);
    if(keys.length<1){
      obj.push(src[i]);
      continue;
    }
    objEle = {};
    obj.push(objEle);
    setObject(src[i],objEle);
  }
}

//返回顶级window对象
function topWindow(win){
  if(win==null){
    return null;
  }
  if(win==win.parent){
    return win;
  }
  return topWindow(win.parent);
}

//将{key : value} 转为  key1=val1&key2=val2
function obj2post(obj){
  var res = [];
  if(obj){
    var keys = Object.keys(obj);
    for(var i=0;i<keys.length;i++){
      res.push(keys[i]+"="+urlEncodePro(obj[keys[i]]));
    }
  }
  return res.join('&');
}

//判断目标url是否可以正常加载
function urlExist(url){
  if(!url || url==""){
    return false;
  }
  var oXmlHttp;
  if(window.XMLHttpRequest){
    oXmlHttp = new XMLHttpRequest() ; 
  }else if ( window.ActiveXObject ){
    oXmlHttp = new ActiveXObject("MsXml2.XmlHttp");
  }
  oXmlHttp.open("GET",url,false);
  oXmlHttp.setRequestHeader("CONTENT-TYPE", "application/x-www-form-urlencoded");
  oXmlHttp.send();
  source = oXmlHttp.responseText;
  if(oXmlHttp.status==200 && source && source!=""){
    return true;
  }
  return false;
}


//优化表格，冻结表头 只能处理带thead(其中的单元格必须为th) tbody的表
function optimizeTable(tb,tbArea){
  if(typeof(tb)=="string"){
    tb = $("#"+tb);
  }
  if(tb.length<1){
    return;
  }
  if(!tbArea){
    tbArea = tb.parent();
  }
  var thead = tb.find("thead");
  var tbody = tb.find("tbody");
  if(thead.length<1 || tbody.length<1){
    return;
  }
  var headHeight    = thead.outerHeight();
  var bodyTds       = [];
  var oHeadtrs      = [];
  var fixHeadTr     = null;
  var tdName        = "th";
  var tbodyTrTds    = tbody.find("tr:first").find("td");
  var tbodyTdWidths = [];
  tbodyTrTds.each(function(){
    var node  = $(this);
    var width = node.width();
    bodyTds.push(node);
    tbodyTdWidths.push(parseInt(width)+1);
  });
  for(var i=0;i<bodyTds.length;i++){
    var txt = bodyTds[i].html();
    bodyTds[i].empty().append(['<div style="width:',tbodyTdWidths[i],'px;">',txt,'</div>'].join(''));
  }
  if(bodyTds.length<1){
    return;
  }
  var headThs = null;
  thead.find("tr").each(function(){
    if(headThs!=null){
      return;
    }
    var node = $(this);
    var ths  = node.find(tdName);
    if(ths.length<1){
      tdName = "td";
      ths = node.find(tdName);
    }
    if(ths.length==bodyTds.length){
      headThs    = ths;
      fixHeadTr = node;
    }else{
      node.hide();
      oHeadtrs.push(node);
    }
  });
  if(headThs==null){
    return;
  }
  for(var i=0;i<tbodyTdWidths.length;i++){
    var node = headThs.eq(i);
    var txt   = node.text();
    node.empty().append(['<div style="width:',tbodyTdWidths[i],'px;">',txt,'</div>'].join(''));
  }
  if(tbArea==null){
    tbArea = tb.parent();
  }else if(!(tbArea instanceof jQuery)){
    tbArea = $(tbArea);
  }
  if(tbArea.length<1){
    return;
  }
  tbArea.css("position","relative");
  var offset = tb.offset();
  var offsetTop = parseInt(offset.top);
  thead.css("position","absolute").css("left",offset.left+"px").css("top",offset.top+"px");
  tb.css("margin-top",(headHeight+4)+"px");
  //在将表头分离出去以后，要重新定位一下表体位置
  offset = tb.offset();
  offsetTop = parseInt(offset.top);
  tbArea.on("scroll",function(){
    var scrollTop;
    if(this==document){
      scrollTop = this.documentElement.scrollTop;
    }else{
      scrollTop = this.scrollTop;
    }
    if(scrollTop<offsetTop){
      thead.css("top",(offsetTop-headHeight+1)+"px");
    }else{
      thead.css("top",scrollTop+"px");
    }
    
  });
  thead.css("position","absolute").css("left",offset.left+"px").css("top",(offsetTop-headHeight+1)+"px");
  tb.css("margin-top",(headHeight+4)+"px");
  if(fixHeadTr){
    var fixWidth = fixHeadTr.width();
    tb.width(fixWidth); //固定表格宽度，否则窗口宽度变小，表格会自动压缩宽度，导致表头和表体列宽度又不一致
    var tds;
    var td;
    var width;
    var autoWidthTds;
    for(var i=0;i<oHeadtrs.length;i++){
      tds          = oHeadtrs[i].find(tdName);
      autoWidthTds = [];
      for(var j=0;j<tds.length;j++){
        td    = tds.eq(j);
        width = cssValue(td.css("width"));
        if(width>0){
          fixWidth -= width;
        }else{
          autoWidthTds.push(td);
        }
      }
      if(autoWidthTds.length>1){
        fixWidth = parseInt(fixWidth/autoWidthTds.length);
      }
      if(fixWidth>30){
        fixWidth -= 30;
      }
      for(var j=0;j<autoWidthTds.length;j++){
        autoWidthTds[j].width(fixWidth);
      }
      oHeadtrs[i].show();
    }
  }
  $(window).on("resize",function(){
    tb.css("margin-top",(headHeight+4)+"px");
    offset = tb.offset();
    offsetTop = parseInt(offset.top);
    thead.css("top",(offsetTop-headHeight+1)+"px");
  });
}



//替换字符串str中全部findStr为replaceStr
//另外，该方法支持批量替换一组字符串的方法,即：
//str = swap(str,"skey1","rval1","skey2","rval2",skey3","rval3"); 
function swap(str,findStr,replaceStr){
  if(arguments.length<1){
    return "";
  }
  if(arguments.length<2){
    return arguments[0];
  }
  var args = [];
  for(var i=0;i<arguments.length;i++){
    args.push(arguments[i]);
  }
  if(args.length<3){
    args.push("");
  }
  var reStr = args[0];
  var point = 2;
  while(point<args.length){
    while(reStr.indexOf(args[point-1])!=-1){
      reStr = reStr.replace(args[point-1],args[point]);
    }
    point+=2;
  }
  return reStr;
}

//阻塞延时 delay表示的毫秒数
function sleep(delay) {
  var start = (new Date()).getTime();
  while ((new Date()).getTime()-start<delay) {
    continue;
  }
}

//返回日期值
function d(){
  return (new Date()).format("yyyy-MM-dd");
}

//返回时间值
function dt(){
  return (new Date()).format("yyyy-MM-dd HH:mm:ss");
}

//返回时间戳
function ts(){
  return (new Date()).format("yyyy-MM-dd HH:mm:ss SSS");
}